在一次使用axios中实现文件上传时遇到一个问题。觉得对于上传这方面还不是很了解,就决定好好了解一下这方面的知识。
首先列出问题:
我使用的是FormData实现的上传,因为移动端浏览器版本一般比较高,所以不考虑兼容性问题。
代码是这样的:
changefile(file){
var forms = new FormData()
var configs = {
headers:{'Content-Type':'multipart/form-data'}
};
forms.append('file',file.target.files[0])
this.axios.post(this.$config.uploadImg,forms ,configs).then(res=>{
console.log(res)
})
}
后台接受的参数也是file。
因为是上传文件,所以把headers的content-type设为了multipart/form-data,也没毛病,但是测试了发现报错。
请求体也没有。
应该是请求体和请求类型不一样吧,请求类型设置的是form-data,请求体应该是一个文件,难道不是文件吗。
突然想到之前有对axios做过请求拦截,是不是那里改变了请求体。
axios.interceptors.request.use((config) => {
Vue.$vux.loading.show({
text: 'Loading'
})
if(config.method === 'post'){
if(config.headers['Content-Type'] !== 'application/json'){
config.data = qs.stringify(config.data);
}else{
config.data = config.data;
}
}
return config;
},(error) =>{
return Promise.reject(error);
});
果然!这里返回了一个对象。把拦截去掉就好了。
既然问题原因找到了,那么就得想怎么解决了,这里的拦截是对参数进行序列化的,如果不写在这里那么所有的接口请求都得写那岂不是麻烦死。
看了后发现是不是傻,只有一种情况需要qs序列化,那就是type为application/x-www-form-urlencoded。
所以只要设置默认type为application/x-www-form-urlencoded
axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded';
然后判断一个就可以了。
当你需要上传文件时,单独设置type即可,那样就不会进入判断。
注意:如果不设置axios的默认type,那么axios会自动根据传的参数,来选择使用什么type。