直接在前端使用阿里云的oss服务向oss上传文件有现成的js写的sdk
项目地址:https://github.com/aliyun-UED/aliyun-sdk-js
使用js上传的example地址:https://github.com/aliyun-UED/oss-js-upload
使用上面的example中的例子做好相关的配置后可以直接进行文件的上传操作,但是当文件的上传大小超过切片大小时,会对改文件进行切片上传操作,这个时候,文件总是在上传成功后进行文件的拼接操作时失败,这个时候注意了,在里面有几个坑。
1.由于是使用的跨域访问的方式进行的文件上传操作所以先要设置允许跨域访问,在oss的访问规则中添加“Access-Control-Allow-Origin”的访问权限 response的头部信息中添加“Access-Control-Allow-Origin”
2.由于是跨域访问,所以返回后的response的头部信息中的head的值是无法获取的,分片上传时,很重要的一个值ETag是存放在response的head里面的,此时,这个值根本取不到
针对aliyun-UED所给的sdk和example文件分片上传失败的bug,解决方案如下:
当进行跨域访问的时候,要想可以读取response中头部信息需要在response头部信息中添加"Access-Control-Expose-Headers“值为允许web端访问得到header值,但是很可惜,服务器端是不受控的,这个解决方案被淘汰了。
阅读阿里云的oss帮助文档,oss提供了一个listparts的功能,我们可以在所有的全部上传成功后进行listparts的请求获取所有的分片信息,取出返回的分片信息进行重组后,使用重组后的数据进行文件拼接请求,这样文件就上传成功了,部分实现代码如下:
1 var complete = function () { 2 // console.log("Completing upload..."); 3 4 for (var i in multipartMap.Parts) { 5 delete multipartMap.Parts[i].loaded; 6 } 7 8 var doneParams = { 9 Bucket: self.bucket, //self._config.bucket, 10 Key: uploadfile.OssUploadControlParm.Key, //self.keygeneratefunc(self,uploadfile), //options.key, 11 CompleteMultipartUpload: multipartMap, 12 UploadId: uploadId 13 }; 14 15 self.oss.listParts({//获取分片 16 UploadId: uploadId, 17 Bucket: self._config.bucket, 18 Key: options.key 19 }, function (err, data) { 20 var parts = data.Parts; 21 multipartMap.Parts = []; 22 var part = null; 23 for (var i = 0; i < parts.length; i++) { 24 part = parts[i]; 25 multipartMap.Parts.push({ 26 PartNumber: part.PartNumber, 27 ETag: part.ETag 28 }); 29 } 30 self.oss.completeMultipartUpload(doneParams, callback); 31 }); 32 33 };
注意红色的代码,这个就是对example中分片上传失败的bug的修复