微信云开发,后台node.js环境,使用axios中post请求上传到“云存储”,遇到的一系坑。如果使用request-promise就没有这么坑。
//向云存储上传文件
static async upLoadFile(path,file){
const ACCESS_TOKEN = await AccessToken.getAccessToken();
let res = await axios.post(`/tcb/uploadfile?access_token=${ACCESS_TOKEN}`,
{
"env": wx.cloudID,
"path":path,
})
//console.log(res);
if(res.data.errcode!==0){
let errcode = res.data.errcode;
let errmsg = res.data.errmsg;
return {errcode,errmsg}
}
const info= res.data;
let formData= new FormData();
formData.append('key',path)
formData.append('Signature',info.authorization)
formData.append('x-cos-security-token',info.token)
formData.append('x-cos-meta-fileid', info.cos_file_id)
formData.append('file',fs.createReadStream(file.path))
const headers = formData.getHeaders();
// 获取form-data长度
formData.getLength(async (err, length)=>{
if (err) {
formData._error(err)
return ;
}
// //设置长度,important!!!
headers['content-length']=length;
headers.post=formData.getHeaders()
let newAxios = new axios.create({baseURL:'',headers:{}});
try{
let res = await newAxios.post(info.url,formData,{headers}
)
.then(res=>{ console.log("上传成功",res.data);})
.catch(res=>{ console.log('err :',res); return res})
return res;
}catch(e){
console.log('errs',e)
return e;
}
})
}
需要使用npm包 “npm i form-data",
const FormData=require('form-data');
一定要注意在headers:中'content-type':'multipart/form-data',不能同时存在两个content-type类型如下:
headers: {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'multipart/form-data; boundary=--------------------------315983526783439086643778',
'Content-type': 'application/json',
'content-length': 779532,
'User-Agent': 'axios/0.19.2'
},
后台会报错》》》
data: "\n" +
'
'\tMethodNotAllowed
\n' +
'\t
'\t
'\t
'\t
'
'\n'
},
isAxiosError: true,
toJSON: [Function]
在使用axios发送post请求时,默认的请求头Content-Type
的属性值为application/json
,这个时候浏览器会分两次发送请求,首先使用OPTION方法发送请来询问服务对请求是否支持,若不支持,则报错,终止请求的发送。
headers.post=formData.getHeaders() ,设置进行覆盖,确保只有一个Content-Type,
参考:https://www.cnblogs.com/libin-1/p/6607945.html
同时注意要设置headers content-length长度 headers['content-length']=length;
参考文献:https://blog.csdn.net/u013379553/article/details/104871118
使用axios时,以上几点需要注意。
如果使用request-promise就没有这么多事情。代码如下:
//向云存储上传文件
static async upLoadFile(path,file){
//上传第二步。
// const options = {
// method: 'POST',
// uri: `https://api.weixin.qq.com/tcb/uploadfile?access_token=${ACCESS_TOKEN}`,
// body: {
// path,
// "env": wx.cloudID,
// },
// json: true // Automatically stringifies the body to JSON
// };
// const info =await rp(options).then(res => {return res}).catch(err=>console.log(err))
//CallHttpFunction._uploadPost(res.data,path,file)
// console.log(info)
//以下为request-promise
/**
*
const params = {
// method: 'POST',
// headers: {
// 'content-type': 'multipart/form-data'
// },
// uri: info.url+1,
// formData: {
// key: path,
// Signature: info.authorization,
// 'x-cos-security-token': info.token,
// 'x-cos-meta-fileid': info.cos_file_id,
// file: fs.createReadStream(file.path)
// },
// json: true
// }
// await rp(params).then(res=>console.log(res).catch(err=>console.log(err)))
// return info.file_id
*/