一、整体思路
- 客户端先向服务端发送请求,请求格式如下
- ossPaht:oss绝对地址
- fileExt:文件后缀类型
- 服务端签名,返回数据,格式如下
- signedUrl上传目标地址
- cdnUrl下载可使用地址
- contentType文件类型
- 通过服务端返回的signedUrl,携带上传的文件请求signedUrl直传OSS
二、问题
-
跨域(这个不需要前端解决)
-
协议冲突问题
服务端返回的signedUrl是http协议但是客户端域名却是https,https无法向http发送请求
解决方案:
去掉http再发送请求,这样子请求的协议就会根据客户端域名的协议来,客户端是http请求就是http,如果是https就是https
原本的请求url格式:
http://oss-cn-hangzhou.aliyuncs.com/xxx
修改后的url格式:
//oss-cn-hangzhou.aliyuncs.com/xxx
-
上传超时、限制文件大小
解决完协议冲突问题,发现上传文件到一定大小便会传输中断,以为阿里云也有传输文件大小限制的问题,后面百度才知道axios设置的timeout时间一到便会中断传输,自己去查看控制台,请求的时间正好的axios的timeout时长,只需要单独配置一下上传请求的timeout时间即可, 代码如下
// file是要上传的文件, 这里不需要使用formData axios .put('//oss-cn-hangzhou.aliyuncs.com/xxx', file, { timeout: 3600000,// 超时时间 headers: { 'Content-Type': this.contentType, }, onUploadProgress: (event) => { // 配置进度条 that.setProgress(event, file, that); }, }) .then((res) => { console.log(res); }.catch((err) => { console.log(err); });
不过这里上传成功后res是没有任何内容的,但是进度条是能够正常配置,下面也有使用fetch上传的解决方案,但是由于fetch配置进度条过于繁琐,需求是要上传大文件,进度条不可缺少,所以最终还是选择了axios。
三、fetch
/** * @name: uploadToOSS * @description: 通过阿里云临时授权直传阿里云 * @param {String} file 文件 * @param {String} signedUrl PUT上传 GET获取 * @param {String} contentType 文件类型 不传会出现上传校验失败 */ async function uploadToOSS({ file, signedUrl, contentType }) { if (!signedUrl) { return; } return fetch(signedUrl, { method: "PUT", headers: { "Content-Type": contentType, "Content-Length": file.length }, body: file }); }