震惊! axios 上传formdata图片有坑 老师:重拳出击 有办法解决吗
来源:9-10 HTTP API调用云存储上传文件并保存云数据库
慕粉2313086611
2020-09-09
老师您好, axios 发送的是json,而发送图片格式是multipart。请问涉及到 header body 数据格式之类的问题该 解决呢,或者有合适的解决方案可以推荐吗。
3回答
-
1、状态码405应该指的是不允许使用此方法请求服务器的资源
2、这部分功能之前使用request-promise是没有问题的,改成axios会出现此问题,所以首先想到的是去axios的官网上看下对于multipart/form-data这种方式如何来构造:https://www.npmjs.com/package/axios
然后在这里发现一句话:
然后我又找到了这个:https://github.com/axios/axios/issues/789
从这里应该能看出来axios对于multipart/form-data这种方式在node方面支持应该是有点问题。
上面我看到这个问题的时候分析的过程。
那有没有替代的方式呢?在request-promise不推荐使用后,官方有给出对于request-promise的替代列表:https://github.com/request/request/issues/3143 这个列表中其他库对于multipart/form-data的支持情况我暂时还没有尝试过所以暂时还没法给出准确答案,这个我们可以来试试列表中的其他库是否支持。
另外我能想到的替代方案:
1、继续使用request,虽然官方不维护了,但使用还是没问题的
2、直接使用腾讯云API来操作云存储,具体方式可以参考文档: https://docs.cloudbase.net/api-reference/server/node-sdk/storage.html#uploadfile
以上是我目前对于这个问题的回答,如有错误或者不完善的地方还请大家来共同探讨,或者如果大家发现更好的解决方式我们也一起来交流,共同进步。
112020-09-10 -
TallMessiWu
2021-09-08
async upload(ctx) { const file = ctx.request.files.file const path = `swiper/${Date.now()}-${Math.random()}-${file.name}` const ACCESS_TOKEN = await getAccessToken() const url = `https://api.weixin.qq.com/tcb/uploadfile?access_token=${ACCESS_TOKEN}` const info = await axios.post(url, { path, env: ctx.state.env, } ).then( (res) => { return res.data } ).catch( function (err) { // post failed... } ) const 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) console.log(file.path) formData.append('file', fs.createReadStream(file.path)) const headers = formData.getHeaders(); // 必须用getLength来获取长度 否则可能会发生图片只有一半被上传 formData.getLength(async function (err, length) { if (err) { return; } //设置content-length属性 headers['content-length'] = length; await axios.post(info.url, formData, {headers}).then((res) => { console.log('上传成功') return res }).catch(function (error) { console.log('上传失败') console.log(error) }) }) return info.file_id },
如果把headers['content-length'] 随便设置成4000的话,会产生图片只上传了一半的现象。我想这个属性可能跟文件大小相关联。https://blog.csdn.net/u013379553/article/details/104871118 根据之前同学提供的这个链接,我综合了一下几位同学的方法。这样就完成了用axios来实现上传文件功能了。要注意的是比起老师课上的代码,这个方法多用了一个FormData模块。因此在文件的开头需要有
const FormData = require("form-data")
来导入模块。同时需要在终端输入
npm install form-data
来安装包。
40 -
慕容9467124
2021-01-19
const uri = info.url
const 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();
const len = 4000 //
headers['content-length'] = len; //加上这两行代码就可以上传成功了
await axios.post(uri, formData, { headers }).then((res) => {
console.log(res)
console.log('上传成功')
return res
}).catch(function (error) {
console.log('上传失败')
console.log(error)
})
/////////////
//我也是遇到这个问题,百度了好久,最后是看到一个帖子 https://blog.csdn.net/u013379553/article/details/104871118
说是要给 headers 加一个属性 content-length 我随便设了一个4000,然后重新调试发现居然上传成功了
132021-05-29
相似问题