启用阿里云对象存储OSS的“服务端签名后直传”后,测试文件上传功能,服务端签名数据能成功获取,详情如下:
{
"msg":"success","code":0,"data":{
"accessid":"L***t","policy":"ey***XX0=","signature":"EqsbPoxA/V***I=","dir":"2021-01-07/","host":"https://***.oss-cn-beijing.aliyuncs.com","expire":"1609993896"}}
但是,后续文件的上传操作却未执行。
问题原因:src\components\upload\singleUpload.vue中beforeUpload(file)的policy()方法详情如下:
beforeUpload(file) {
let _self = this
return new Promise((resolve, reject) => {
policy()
.then(response => {
console.log('返回的数据:', response)
_self.dataObj.policy = response.data.policy
_self.dataObj.signature = response.data.signature
_self.dataObj.ossaccessKeyId = response.data.accessid
_self.dataObj.key = response.data.dir + getUUID() + '_${filename}'
_self.dataObj.dir = response.data.dir
_self.dataObj.host = response.data.host
resolve(true)
})
.catch(err => {
reject(false)
})
})
}
policy()方法获取数据需要一个data对象。而OssController详情如下:
public Map<String, String> policy() {
......
Map<String, String> respMap = null;
......
return respMap ;
}
其返回值是一个Map类型,显然不是policy()方法所需要的。
解决办法:修改OssController如下:
public R policy() {
......
Map<String, String> respMap = null;
......
return R.ok().put("data",respMap);
}
修改之后,再次测试,出现新的报错:
Access to XMLHttpRequest at 'http://***.oss-cn-beijing.aliyuncs.com/' from origin 'http://localhost:8001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested resource. upload.js?c0e8:599 POST http://***.oss-cn-beijing.aliyuncs.com/ net::ERR_FAILED
新问题原因:
浏览器直接将文件及下面的dataObj以post方式提交给对象存储,产生了跨域请求,在未进行跨域设置的前提下,该请求遭到拦截。
data() {
return {
dataObj: {
policy: '',
signature: '',
key: '',
ossaccessKeyId: '',
dir: '',
host: ''
// callback:'',
},
dialogVisible: false
}
}
新问题解决办法:
参考阿里云官方文档《服务端签名后直传》中“代码示例”的《Java》、《Python》、《PHP》或《GO》的“步骤3:修改CORS”,详情节选如下:
客户端进行表单直传到OSS时,会从浏览器向OSS发送带有Origin的请求消息。OSS对带有Origin头的请求消息会进行跨域规则(CORS)的验证。因此需要为Bucket设置跨域规则以支持Post方法。
1、登录OSS管理控制台。
2、单击Bucket列表,之后单击目标Bucket名称。
3、单击权限管理 > 跨域设置,在跨域设置区域单击设置。
4、单击创建规则,配置如下:
来源:* (* 代表所有请求);
允许Methods:POST;
允许Headers:*
(其它选项默认即可。)
设置完成后,测试上传成功。
至此,服务端签名后直传相关的主要问题已经解决。