如何通过Web端直传文件(Object)到OSS
Web端上传OSS介绍
用户在浏览器或App端上传文件到应用服务器,应用服务器再把文件上传到OSS。具体流程如下图所示。
和数据直传到OSS相比,以上方法存在以下缺点:
- 上传慢:用户数据需先上传到应用服务器,之后再上传到OSS,网络传输时间比直传到OSS多一倍。如果用户数据不通过应用服务器中转,而是直传到OSS,速度将大大提升。而且OSS采用BGP带宽,能保证各地各运营商之间的传输速度。
- 扩展性差:如果后续用户数量逐渐增加,则应用服务器会成为瓶颈。
- 费用高:需要准备多台应用服务器。由于OSS上行流量是免费的,如果数据直传到OSS,将节省多台应用服务器的费用。
本文主要介绍如何基于Post Policy的使用规则在服务端通过各种语言代码完成签名,然后通过表单直传数据到OSS。由于服务端签名直传无需将AccessKey暴露在前端页面,相比JavaScript客户端签名直传具有更高的安全性。
- 用户向应用服务器请求上传Policy和回调。
javascript
1let params = { 2 "expire": "xxx", 3 "policy": "xxx", 4 "signature": "xxx", 5 "accessid": "xxx", 6 "host": "xxx", 7 "dir": "xxx" 8 }; 9 axios.get('/getOssParams').then(result=>{ 10 params = result.data 11 })
- 应用服务器返回上传Policy和签名给用户。
javascript
1var dayjs = require('dayjs'); 2var crypto = require('crypto'); 3var nanoid = require('nanoid'); 4 var config = { 5 dirPath: "upload/", 6 bucket: "xxx", 7 region: "xxxx", 8 accessKeyId: "xxxx", 9 accessKeySecret: "xxxxx", 10 expAfter: 1000*60*5, // 签名失效时间,毫秒 11 maxSize: 1024*1000*1024*10, // 文件最大的 size B 12 } 13 // 过期时间 14 const expire = new Date().getTime() + config.expAfter; 15 const expiration = new Date(expire).toISOString(); 16 17 const dir = config.dirPath +dayjs().format('YYYY/MM/DD') + "/" + nanoid.nanoid() 18 // 上传文件名 19 const policyString = JSON.stringify({ 20 expiration, 21 conditions: [ 22 ["content-length-range", 0, config.maxSize], 23 ["starts-with", "$key", dir], 24 ], 25 }); 26 27 const policy = Buffer.from(policyString).toString("base64"); 28 29 const signature = crypto 30 .createHmac("sha1", config.accessKeySecret) 31 .update(policy) 32 .digest("base64"); 33 34 //返回参数 35 const params = { 36 expire, 37 policy, 38 signature, 39 accessid: config.accessKeyId, 40 host: "https://oss.mukang.net", 41 dir, 42 };
- 用户直接向OSS发送文件上传请求。
javascript
1 const files = document.querySelector('input[type="file"]') 2 var formData = new FormData(); 3 const suffix = files[0].name.slice( 4 files[0].name.lastIndexOf(".") 5 ); 6 const filename = Date.now() + suffix; 7 8 formData.append("key", params.dir + "/" + filename); 9 formData.append("policy", params.policy); 10 formData.append("OSSAccessKeyId", params.accessid); 11 formData.append("success_action_status", "200"); 12 formData.append("signature", params.signature); 13 formData.append("file", files[0]); 14 15 axios 16 .post(params.host, formData, { 17 headers: { "Content-Type": "multipart/form-data" }, 18 onUploadProgress: function (progressEvent) { 19 console.log("进度", progressEvent.loaded / progressEvent.total); 20 }, 21 }) 22 .then((result) => { 23 console.log("result.data ===== ", params.hosts + '/' + params.dir + filename); 24 }); 25
阅读量:2474发布日期:2022-04-29 14:09:16
博客描述
OSS可用于图片、音视频、日志等海量文件的存储。各种终端设备、Web网站程序、移动应用可以直接向OSS写入或读取数据。OSS支持流式写入和文件写入两种方式。