解決axios發(fā)送post請(qǐng)求上傳文件到后端的問(wèn)題(multipart/form-data)
項(xiàng)目場(chǎng)景:
后端:實(shí)現(xiàn)了一個(gè)文件上傳服務(wù)接口,可以接收前端傳遞過(guò)來(lái)的MultipartFile文件,并存儲(chǔ)到服務(wù)器本地中。
前端:獲取type為file的<font>標(biāo)簽中的文件,使用axioshttp請(qǐng)求庫(kù),發(fā)送post請(qǐng)求,將文件發(fā)送給后端。
問(wèn)題描述
在js中發(fā)送上傳文件請(qǐng)求的常規(guī)代碼如下:
new一個(gè)FormData對(duì)象,使用append方法將文件添加到表單中FormData專門用于js中發(fā)送multipart/form-data格式請(qǐng)求append方法的key為表單中的name屬性,即后端需要接收的參數(shù)名
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);
}實(shí)際運(yùn)行以上這段代碼時(shí),會(huì)發(fā)現(xiàn)后端報(bào)500錯(cuò)誤如下:
Caused by: java.io.IOException:
org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
大概的意思是說(shuō),后端無(wú)法識(shí)別到傳遞來(lái)的文件中的boundary,從而無(wú)法區(qū)分一個(gè)文件的內(nèi)容從報(bào)文的哪個(gè)地方開(kāi)始,又從報(bào)文的哪個(gè)地方結(jié)束,最終導(dǎo)致文件上傳失敗。
原因分析:
分析以上這種情況的原因,是因?yàn)槲以诎l(fā)送請(qǐng)求時(shí)將請(qǐng)求頭中Content-Type屬性給寫死為multipart/form-data,瀏覽器無(wú)法自動(dòng)給我們的報(bào)文添加boundary
我嘗試將前端請(qǐng)求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);
}再次發(fā)送請(qǐng)求,這次仍然沒(méi)有請(qǐng)求成功。服務(wù)器沒(méi)有報(bào)錯(cuò)了,但是后端獲取不到文件數(shù)據(jù)。繼續(xù)分析請(qǐng)求報(bào)文,發(fā)現(xiàn)屬性值變?yōu)?code>application/x-www-form-urlencoded,這是發(fā)送普通的表單,肯定是無(wú)法正確將文件送達(dá)的。
解決方案:
在查閱了網(wǎng)上大量的帖子之后得知,axios在請(qǐng)求發(fā)送出去之前會(huì)進(jìn)行一次攔截,自動(dòng)給我們的請(qǐng)求設(shè)置一些參數(shù)。上面會(huì)出現(xiàn)application/x-www-form-urlencoded這個(gè)參數(shù)就是因?yàn)?code>axios設(shè)置了post請(qǐng)求的默認(rèn)請(qǐng)求頭,如果我們沒(méi)有在config中指定其它請(qǐng)求頭的話,就會(huì)使用默認(rèn)的。
又了解到,發(fā)送multipart/form-data格式的請(qǐng)求時(shí),不需要我們自己指定Content-Type屬性,由瀏覽器自動(dòng)幫我們?nèi)ピO(shè)置。
那么解決問(wèn)題的關(guān)鍵就是不讓axios幫我們自動(dòng)配置
axios的config中有一個(gè)transformRequest屬性,官方的解釋是可以在請(qǐng)求發(fā)送之前讓我們?nèi)藶楦深A(yù)。屬性值是一個(gè)數(shù)組,里面可以定義一個(gè)函數(shù),接收兩個(gè)參數(shù),分別是data和headers。data就是我們剛剛定義的FormData對(duì)象,headers里面則是axios預(yù)定義的請(qǐng)求頭。
打印headers:

將post屬性中的Content-Type屬性刪掉即可解決問(wèn)題。
最終代碼如下:
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請(qǐng)求默認(rèn)的Content-Type
delete headers.post['Content-Type']
return data
}],
data: formData
})
console.log(res.data);
}以上的解決方法是我不斷試錯(cuò)之后得出來(lái)的,網(wǎng)上關(guān)于這個(gè)問(wèn)題的很多帖子都不能解決,氣死我了。。。希望這篇帖子能幫助大家避免踩這個(gè)坑吧~
到此這篇關(guān)于如何使用axios發(fā)送post請(qǐng)求上傳文件到后端(multipart/form-data)的文章就介紹到這了,更多相關(guān)axios發(fā)送post請(qǐng)求上傳文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue全家桶實(shí)踐項(xiàng)目總結(jié)(推薦)
本篇文章主要介紹了Vue全家桶實(shí)踐項(xiàng)目總結(jié)(推薦),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
vue + node如何通過(guò)一個(gè)Txt文件批量生成MP3并壓縮成Zip
這篇文章主要介紹了vue + node如何通過(guò)一個(gè)Txt文件批量生成MP3并壓縮成Zip的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06
vue使用window.open()跳轉(zhuǎn)頁(yè)面的代碼案例
這篇文章主要介紹了vue中對(duì)window.openner的使用,vue使用window.open()跳轉(zhuǎn)頁(yè)面的代碼案例,本文通過(guò)實(shí)例代碼給大家詳細(xì)講解,需要的朋友可以參考下2022-11-11
vue使用watch監(jiān)聽(tīng)props的技巧分享
這篇文章主要為大家詳細(xì)介紹了vue使用watch監(jiān)聽(tīng)props的一些小建議,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12
vue中動(dòng)態(tài)參數(shù)與計(jì)算屬性的使用方法
在平時(shí)vue開(kāi)發(fā)中,我們經(jīng)常會(huì)用到計(jì)算屬性(計(jì)算屬性只有在它的相關(guān)依賴發(fā)生改變時(shí)才會(huì)重新求值)來(lái)計(jì)算我們需要的數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于vue中動(dòng)態(tài)參數(shù)與計(jì)算屬性使用的相關(guān)資料,需要的朋友可以參考下2021-08-08
詳解IOS微信上Vue單頁(yè)面應(yīng)用JSSDK簽名失敗解決方案
這篇文章主要介紹了詳解IOS微信上Vue單頁(yè)面應(yīng)用JSSDK簽名失敗解決方案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
vue 實(shí)現(xiàn)tab切換保持?jǐn)?shù)據(jù)狀態(tài)
這篇文章主要介紹了vue 實(shí)現(xiàn)tab切換保持?jǐn)?shù)據(jù)狀態(tài),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07
vue項(xiàng)目中使用this.$confirm解析
這篇文章主要介紹了vue項(xiàng)目中使用this.$confirm方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09

