当前位置:首页 > 谈天说地

解决axios发送post请求上传文件到后端的问题(multipart/form-data)

34资源网2022-05-22632

项目场景:

后端:实现了一个文件上传服务接口,可以接收前端传递过来的multipartfile文件,并存储到服务器本地中。
前端:获取type为file的<font>标签中的文件,使用axioshttp请求库,发送post请求,将文件发送给后端。

问题描述

在js中发送上传文件请求的常规代码如下:

  • new一个formdata对象,使用append方法将文件添加到表单中
  • formdata专门用于js中发送multipart/form-data格式请求
  • append方法的key为表单中的name属性,即后端需要接收的参数名
async handleuploadfile(event) {
  const file = event.target.files[0]
  let formdata = new formdata()
  formdata.append('files', file)
  const res = await service({
    url: '/api/files/upload',
    method: 'post',
    headers: {
       'content-type': 'multipart/form-data'
    },
    data: formdata
  })
  console.log(res.data);
}

实际运行以上这段代码时,会发现后端报500错误如下:

caused by: java.io.ioexception:
org.apache.tomcat.util.http.fileupload.fileuploadexception: the request was rejected because no multipart boundary was found

大概的意思是说,后端无法识别到传递来的文件中的boundary,从而无法区分一个文件的内容从报文的哪个地方开始,又从报文的哪个地方结束,最终导致文件上传失败。

原因分析:

分析以上这种情况的原因,是因为我在发送请求时将请求头中content-type属性给写死为multipart/form-data,浏览器无法自动给我们的报文添加boundary

我尝试将前端请求config中,headers配置移除,如下:

async handleuploadfile(event) {
  const file = event.target.files[0]
  let formdata = new formdata()
  formdata.append('files', file)
  const res = await service({
    url: '/api/files/upload',
    method: 'post',
    data: formdata
  })
  console.log(res.data);
}

再次发送请求,这次仍然没有请求成功。服务器没有报错了,但是后端获取不到文件数据。继续分析请求报文,发现属性值变为application/x-www-form-urlencoded,这是发送普通的表单,肯定是无法正确将文件送达的。

解决方案:

在查阅了网上大量的帖子之后得知,axios在请求发送出去之前会进行一次拦截,自动给我们的请求设置一些参数。上面会出现application/x-www-form-urlencoded这个参数就是因为axios设置了post请求的默认请求头,如果我们没有在config中指定其它请求头的话,就会使用默认的。

又了解到,发送multipart/form-data格式的请求时,不需要我们自己指定content-type属性,由浏览器自动帮我们去设置。

那么解决问题的关键就是不让axios帮我们自动配置

axios的config中有一个transformrequest属性,官方的解释是可以在请求发送之前让我们人为干预。属性值是一个数组,里面可以定义一个函数,接收两个参数,分别是data和headers。data就是我们刚刚定义的formdata对象,headers里面则是axios预定义的请求头。

打印headers:

将post属性中的content-type属性删掉即可解决问题。

最终代码如下:

async handleuploadfile(event) {
  const file = event.target.files[0]
  let formdata = new formdata()
  formdata.append('files', file)
  const res = await service({
    url: '/api/files/upload',
    method: 'post',
    transformrequest: [function(data, headers) {
      // 去除post请求默认的content-type
      delete headers.post['content-type']
      return data
    }],
    data: formdata
  })
  console.log(res.data);
}

以上的解决方法是我不断试错之后得出来的,网上关于这个问题的很多帖子都不能解决,气死我了。。。希望这篇帖子能帮助大家避免踩这个坑吧~

到此这篇关于如何使用axios发送post请求上传文件到后端(multipart/form-data)的文章就介绍到这了,更多相关axios发送post请求上传文件内容请搜索萬仟网以前的文章或继续浏览下面的相关文章希望大家以后多多支持萬仟网!

版权声明:34楼发布

本文链接:https://www.34l.com/post/15943.html

分享给朋友:

相关文章

最傻的六种员工离职理由,希望你不是其中一员

最傻的六种员工离职理由,希望你不是其中一员

春节后,今年的中国员工离职率应该是最低的。但是职场上,还是会有很多员工提离职。离职原因各种各样, 不开心,不舒服,工资少,学不到东西等等。那么,最傻的六种员工离职是哪些呢?…

疫情还是很严峻,最近去超市都要检测了

疫情还是很严峻,最近去超市都要检测了

疫情还是很严峻,最近去超市也要各种检测了,记得前不久我去超市还是比较宽松的,基本上没有专门的检测员,口罩也不用戴。最近可能是外省一些地区疫情比较严重了,所以温州这边现在检测也更加严格了,我最近去超市买东西都要各种检测,买个菜呀,买些零食吃的…

g系列cpu性能排行(英特尔u系列和g系列)

g系列cpu性能排行(英特尔u系列和g系列)

去年10月,AMD正式发布Zen 3架构锐龙5000系列处理器,单线程和多线程性能实现“质”的飞跃,反超当时的10代酷睿处理器,与后来发布的11代酷睿处理器相比,也丝毫不落于下风。 在这样的大前提下,AMD于4月发布了Zen 3架构锐龙5…

虚拟内存太低怎么设置(电脑磁盘空间不足清理步骤)

虚拟内存太低怎么设置(电脑磁盘空间不足清理步骤)

在电脑的平时使用中,经常会出现内存不足的提示,有时可能小伙伴们会疑惑了,明明自己是16G内存的性能为何也能出现这种提示呢?这是当你在运行多个大程序的时候,对内存的需求非常大,当物理内存不能满足需求时,有可能导致程序关闭而数据保存错误。那么在…

个人微信号怎么更改(设置里的微信密码)

个人微信号怎么更改(设置里的微信密码)

有多少人和我一样,起了一个非常非常中二的名字。当初的年少无知终于可以后悔了。微信号终于!终于!终于可以修改微信号了。(IOS用户请先等等,现在仅支持安卓用户哦) 微信最近推出新功能,允许用户每年修改一次微信号。 TOP1:首先把微信更新到…