请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

震惊! axios 上传formdata图片有坑 老师:重拳出击 有办法解决吗

老师您好, axios 发送的是json,而发送图片格式是multipart。请问涉及到 header body 数据格式之类的问题该 解决呢,或者有合适的解决方案可以推荐吗。


https://img1.sycdn.imooc.com//szimg/5f5895d309d66a4a12040960.jpg


https://img1.sycdn.imooc.com//szimg/5f5895e80956687114560620.jpg

正在回答

3回答

谢成 2020-09-10 01:24:19

1、状态码405应该指的是不允许使用此方法请求服务器的资源

2、这部分功能之前使用request-promise是没有问题的,改成axios会出现此问题,所以首先想到的是去axios的官网上看下对于multipart/form-data这种方式如何来构造:https://www.npmjs.com/package/axios 

然后在这里发现一句话:

https://img1.sycdn.imooc.com/szimg/5f590cbc099173e016801430.jpg

然后我又找到了这个: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


以上是我目前对于这个问题的回答,如有错误或者不完善的地方还请大家来共同探讨,或者如果大家发现更好的解决方式我们也一起来交流,共同进步。




1 回复 有任何疑惑可以回复我~
  • 提问者 慕粉2313086611 #1
    好的,谢谢老师。
    回复 有任何疑惑可以回复我~ 2020-09-10 09:16:19
TallMessiWu 2021-09-08 17:29:42
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

来安装包。

4 回复 有任何疑惑可以回复我~
慕容9467124 2021-01-19 11:57:35

 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,然后重新调试发现居然上传成功了


1 回复 有任何疑惑可以回复我~
  • Zedpjjy #1
    len 可以通过这个函数获得 formData.getLengthSync()
    回复 有任何疑惑可以回复我~ 2021-03-13 18:41:29
  • 我用你的方式,不行啊??  为什么会这样啊?  
    const FormData = require('form-data')  这个安装是npm install form-data  吗?
    回复 有任何疑惑可以回复我~ 2021-05-29 17:15:02
  • let formData = new FormData()
              formData.append('key', path)
              formData.append('Signature', fileData.authorization)
              formData.append('x-cos-security-token', fileData.token)
              formData.append('x-cos-meta-fileid', fileData.cos_file_id)
              formData.append('file', fs.createReadStream(file.path))
              console.log('formData', formData)
              let headers = formData.getHeaders()
              headers['content-type'] = 'multipart/form-data'
              headers['content-length'] = 4000
              await axios.post(fileData.url, formData, {headers}).then(res => {
                console.log('res :>> ', res)
              }).catch(err => {
                console.log('err :>> ', err);
              })
    
    返回还是405
    回复 有任何疑惑可以回复我~ 2021-05-29 17:17:05
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信