后端
:实现了一个文件上传服务接口,可以接收前端传递过来的MultipartFile文件,并存储到服务器本地中。
前端
:获取
type
为
file
的
<form>
标签中的文件,使用
axios
http请求库,发送
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) {
delete headers.post['Content-Type']
return data
}],
data: formData
console.log(res.data);
以上的解决方法是我不断试错之后得出来的,网上关于这个问题的很多帖子都不能解决,气死我了。。。希望这篇帖子能帮助大家避免踩这个坑吧~
我的 个人博客 上线啦,欢迎到访~
import axios from 'axios' //引入
//Vue.use(axios) axios不能用use 只能修改原型链
Vue.prototype.$axios = axios
2. 发送GET请求
axios封装了get方法,传入请求地址和请求参数,就可以了,同样支持Promise。
//不带参数的get请求
let url
vue文件提交 ==>> FormData方式
做Vue项目的时候, 提交数据基本上都是用Axios, 之前做过的表单方面的提交,一直没有空隙进行总结,今天得空进行一下复习和总结:Vue中使用Axios处理包含上传文件的表单提交
可能出现的问题:
1、上传文件应该以什么方式提交, 比如后台是multipart/form-data, 而习惯性以json对象发送数据(实际上大量插件对数据对象也封装了方法, 所以容易忽略)
2、上传文件提交的格式, 以为将对象改成
Axios是通过Promise实现XHR封装,其中Promise是控制手段,XHR是实际发送Http请求的客户端。都是AJAX技术的一种具体实现。
因为vue的火爆让axios成为现在比较流行的异步请求方式。本文章只是针对新手,大佬可以跳过。
我们采put请求修改数据,可以具体修改某一条数据。我们使用get请求可以得到我们想要的具体的数据。,可以采用JSON的形式传输数据。then方法指定成功时候的回调。我们可以操作post请求。
前期需要了解的一些知识
此方法主要是使用FormData数据进行文件的上传;FormData是XMLHttpRequest Level2提供的一个接口对象,提供了一种表单数据的键值对的构造方法,经过它的数据处理可以使用XMLHttpRequest.send( )方法送出;如果送出时的编码类型被设为"multipart/form-data",会使用和表达一样的格式;
使用FormData实例的append()方法或set()方法设置数据,其中append与set区别在于,一个是不会覆盖原值,只添加新值。一
最近在参与一个项目过程中遇到一个问题,相信大部分人都遇到过:
在后端与前端约定好application/json格式传递数据时,因为后台是go强类型语言,在定义api接口时,某些字段要求是整型类型,但是对于前端来说输入框或者从url中的search取到的参数都是字符串,不得不进行前端类型转换。
咋一看,对于接口参数比较少的api前端转换没有什么,但是对于一般的交互复杂,参数比较多的接口,要对大部分参数进行类型转换就是一种吃力不讨好的活。好在后端同学还支持另一种的前后端数据交互格式,即multipart/fo
原来使用vue1.0的时候,我们一直使用ajax来发送请求,当接触新的项目的时候,我们使用了vue2.0,结合着使用了axios来代替ajax。安装axios的话:1-利用npm安装npm install axios –save2、 利用bower安装bower install axios –save3、 直接利用cdn引入<script src="https://unpkg.com/axios/d