OSS Policy方式上传
- 一、 流程对比
- 1.1 普通上传
- 1.2 服务端签名后直传
- 二、获取上传的policy签名配置
- 三、请求OSS上传文件
- 四、调用应用服务器接口同步文件
- 五、关于上传OSS报错注意事项
- 六、附送链接
一、 流程对比
1.1 普通上传
缺点:
- 上传慢:用户数据需先上传到应用服务器,之后再上传到OSS。网络传输时间比直传到OSS多一倍。如果用户数据不通过应用服务器中转,而是直传到OSS,速度将大大提升。
- 扩展性差:如果后续用户多了,应用服务器会成为瓶颈。
- 费用高:需要准备多台应用服务器。由于OSS上传流量是免费的,如果数据直传到OSS,不通过应用服务器,那么将能省下几台应用服务器。
1.2 服务端签名后直传
好处:
- Web端向服务端请求签名,然后直接上传,不会对服务端产生压力,而且安全可靠。
- 但服务端无法实时了解用户上传了多少文件,上传了什么文件。如果想实时了解用户上传了什么文件,可以采用服务端签名直传并设置上传回调。
- 但存在着恶意上传的风险,造成存储空间的浪费
二、获取上传的policy签名配置
根据你们后端提供的get或者post API 请求获取policy直传的签名
接口一般定义为get请求 :/api/Upload/getSignedUrl
后端返回信息:
{
"accessid":"LTAI5tBDFVar1hoq****",
"host":"http://post-test.oss-cn-hangzhou.aliyuncs.com",
"policy":"eyJleHBpcmF0aW9uIjoiMjAxNS0xMS0wNVQyMDoyMzoyM1oiLCJjxb25kaXRpb25zIjpbWyJjcb250ZW50LWxlbmd0aC1yYW5nZSIsMCwxMDQ4NTc2MDAwXSxbInN0YXJ0cy13aXRoIiwiJGtleSIsInVzZXItZGlyXC8i****",
"signature":"VsxOcOudx******z93CLaXPz+4s=",
"expire":1446727949,
"dir":"user-dirs/"
}
字段 | 描述 |
---|---|
accessid | 用户请求的AccessKey ID。 |
host | 用户发送上传请求的域名。 |
policy | 用户表单上传的策略(Policy),Policy为经过Base64编码过的字符串。详情请参见Post Policy。 |
signature | 对Policy签名后的字符串。详情请参见Post Signature。 |
expire | 由服务器端指定的Policy过期时间,格式为Unix时间戳(自UTC时间1970年01月01号开始的秒数)。 |
dir | 限制上传的文件前缀。 |
注意:dir是你要上传到oss bucket下的子目录名称,也就是你要上传的文件在哪个目录下,这个目录可以自己指定,如果这样,就可以客户端get请求的时候携带给后端,这时,API就可以按照个人需求来修改了
get请求可以在url上携带dir名称,也可以用post请求,body的形式传递json给后端,更容易参数扩展
dir目录很重要,在下面的第三点的post请求上传oss的时候,需要传递一个键值对:
“key” : value(dir+文件名)
三、请求OSS上传文件
用户使用Post方法向OSS发送文件上传请求
把上一步请求后端返回给你的那些参数,通过post请求构造body,上传至oss服务器
请求的地址就是服务端返回的host字段:http://post-test.oss-cn-hangzhou.aliyuncs.com
参数就是下面的伪代码:
new_multipart_params = {
// key表示上传到Bucket内的Object的完整路径,例如exampledir/exampleobject.txtObject,完整路径中不能包含Bucket名称。
// filename表示待上传的本地文件名称。
'key' : key + '${filename}',
'policy': policyBase64,
'OSSAccessKeyId': accessid,
// 设置服务端返回状态码为200,不设置则默认返回状态码204。
'success_action_status' : '200',
'signature': signature,
};
注意:这里每一个参数都不能少,success_action_status不传也行,但是OSS默认会返回204状态码,指定200以后,会返回200
这里通过apiPost进行上传测试:
红框内是必传字段,我通过测试得出两个结论:
1.policy签名直传方式中,这个key一定要传递,指定好上面说的那个dir名称,否则会报错,类似policy策略失败问题
2.这种方式不会像我们正常post请求后端那样支持批量上传文件了,因为有key的限制
我尝试了多个file配置多个key,以失败告终
四、调用应用服务器接口同步文件
我们上传到OSS的文件,没设置callback的话,后端并不知道,有两种方法可以同步后端;
方案一:在请求OSS的时候,设置callback,估计oss上传完成会通知后端?
方案二:也是我现在项目做的方式,我们拿到OSS返回200以后,跟后端重新定义接口同步文件信息到后端
五、关于上传OSS报错注意事项
上传报错(返回400,403,405,204)
报错信息 | 解决方案 |
---|---|
204 | 在formData: {}中添加 success_action_status:“200” |
400 | 添加上传的 Key 值,路径也要写正确,/images/test.png 为错误写法(最前面多了个斜杠),正确写法success images/test.png ;另外,阿里云OSS一次只允许上传一张照片。 |
403 | 检测 OSSAccessKeyId,policy,signature 是否填写正确; expiration已过期 |
405 | URL中添加服务器地址 http://post-test.oss-cn-hangzhou.aliyuncs.com 而不能写成 http://post-test.oss-cn-hangzhou.aliyuncs.com/images/test.png这种形式 |
六、附送链接
阿里云服务端签名直传文档
https://help.aliyun.com/document_detail/31926.html?spm=a2c4g.31920.0.0