前言:
每个OSS的用户都会用到上传服务。Web端常见的上传方法是用户在浏览器或App端上传文件到应用服务器,应用服务器再把文件上传到OSS。具体流程如下图所示:
和数据直传到OSS相比,以上方法有三个缺点:
- 上传慢:用户数据需先上传到应用服务器,之后再上传到OSS。网络传输时间比直传到OSS多一倍。如果用户数据不通过应用服务器中转,而是直传到OSS,速度将大大提升。而且OSS采用BGP带宽,能保证各地各运营商之间的传输速度。
- 扩展性差:如果后续用户多了,应用服务器会成为瓶颈。
- 费用高:需要准备多台应用服务器。由于OSS上传流量是免费的,如果数据直传到OSS,不通过应用服务器,那么将能省下几台应用服务器。
整体思路是:前端先向后端获取OSS的权限,然后把图片文件与权限一起发送至OSS服务器
在实现途中出现了两个问题,需要提一下,一个是axios的设置问题:
由于我axios全局设置了axios.defaults.withCredentials = true
;导致报错:
所以这个需要在调接口的时候修改一下:
另外一个失误困扰了我好长时间,一直报400和403的错误!
主要是以为formdata中添加健值的顺序不对!!! 所以一定要注意顺序!!!
完整代码:
html代码
<div class="test">
<input type="file" @change="getfile" id="file"/>
<a @click="upload" href="javascript:;" class='btn'>上传</a>
</div>
js代码
data(){
return {
aliyunOssToken:'',
file:'',
filename:'',
fileUrl:''
}
},
methods: {
//获取上传通行证
getOssToken(){
axios.get('/api/oss/getPolicy').then((res)=>{
if(res.data.code == 200){
this.aliyunOssToken = res.data.data;
}else{
this.$message.error(res.data.message);
}
}).catch(function(error){
console.log(error);
})
},
//获取文件
getfile(e){
this.file = e.target.files[0];
this.filename=this.file.name;
console.log(this.file,this.filename)
},
//上传文件
upload(){
var formData = new FormData();
//注意formData里append添加的键的大小写
formData.append('key', this.aliyunOssToken.dir + this.filename); //存储在oss的文件路径
formData.append('OSSAccessKeyId', this.aliyunOssToken.accessid); //accessKeyId
formData.append('policy', this.aliyunOssToken.policy); //policy
formData.append('Signature', this.aliyunOssToken.signature); //签名
//如果是base64文件,那么直接把base64字符串转成blob对象进行上传就可以了
formData.append("file", this.file);
formData.append('success_action_status', 200); //成功后返回的操作码
//图片地址
this.fileUrl = this.aliyunOssToken.host +'/'+ this.aliyunOssToken.dir + this.filename;
this.axios({
url: this.aliyunOssToken.host,
method:'post',
data:formData,
withCredentials:false,
headers: {
'Content-Type': 'multipart/form-data',
},
}).then(res=>{
console.log(res)
if(res.status==200){
//成功回调
console.log(this.fileUrl)
}else{
//失败回调
this.$message.error('上传失败!');
}
})
}
}