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

 更新时间:2022年05月21日 09:46:51   作者:AmbitiousJun  
这篇文章主要介绍了如何使用axios发送post请求上传文件到后端(multipart/form-data),本文给大家带来了问题原因及解决方案,结合实例代码给大家介绍的非常详细,需要的朋友可以参考下

项目场景:

后端:实现了一个文件上传服务接口,可以接收前端传递过来的MultipartFile文件,并存储到服务器本地中。
前端:获取typefile<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帮我们自动配置

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

打印headers

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请求上传文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue全家桶实践项目总结(推荐)

    Vue全家桶实践项目总结(推荐)

    本篇文章主要介绍了Vue全家桶实践项目总结(推荐),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • vue3自定义hooks/可组合函数方式

    vue3自定义hooks/可组合函数方式

    这篇文章主要介绍了vue3自定义hooks/可组合函数方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • 使用async-validator编写Form组件的方法

    使用async-validator编写Form组件的方法

    本篇文章主要介绍了使用 async-validator 编写 Form 组件的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • vue + node如何通过一个Txt文件批量生成MP3并压缩成Zip

    vue + node如何通过一个Txt文件批量生成MP3并压缩成Zip

    这篇文章主要介绍了vue + node如何通过一个Txt文件批量生成MP3并压缩成Zip的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • vue使用window.open()跳转页面的代码案例

    vue使用window.open()跳转页面的代码案例

    这篇文章主要介绍了vue中对window.openner的使用,vue使用window.open()跳转页面的代码案例,本文通过实例代码给大家详细讲解,需要的朋友可以参考下
    2022-11-11
  • vue使用watch监听props的技巧分享

    vue使用watch监听props的技巧分享

    这篇文章主要为大家详细介绍了vue使用watch监听props的一些小建议,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-12-12
  • vue中动态参数与计算属性的使用方法

    vue中动态参数与计算属性的使用方法

    在平时vue开发中,我们经常会用到计算属性(计算属性只有在它的相关依赖发生改变时才会重新求值)来计算我们需要的数据,下面这篇文章主要给大家介绍了关于vue中动态参数与计算属性使用的相关资料,需要的朋友可以参考下
    2021-08-08
  • 详解IOS微信上Vue单页面应用JSSDK签名失败解决方案

    详解IOS微信上Vue单页面应用JSSDK签名失败解决方案

    这篇文章主要介绍了详解IOS微信上Vue单页面应用JSSDK签名失败解决方案,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • vue 实现tab切换保持数据状态

    vue 实现tab切换保持数据状态

    这篇文章主要介绍了vue 实现tab切换保持数据状态,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • vue项目中使用this.$confirm解析

    vue项目中使用this.$confirm解析

    这篇文章主要介绍了vue项目中使用this.$confirm方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09

最新评论