FormData傳輸JSON同時上傳單個/多個文件問題
背景
最近在開發一個功能時,涉及到向后端接口發送:
- JSON請求參數
- 多個文件
剛開始想通過RequestBody(application/json)形式進行傳值,但是文件不好處理。有一個通過application/json傳輸文件數據的方法,就是將文件轉成base64,然后在后端進行處理。但是這種方式涉及到大文件傳輸的時候,轉成base64會消耗過多成本
于是找來找去找到按form表單的形式提交請求參數(按理來說本該如此),但是如何傳輸json數據倒變成了一個問題,直到找到這么一個文檔,參考之后解決了目前的問題。
https://springdoc.cn/spring-file-upload-json/
解決歷程
- 后端接口:
@PostMapping("/creation")
public void testFormData(@RequestPart("files") MultipartFile[] files,
@RequestPart("dto") Dto dto
) {
System.out.println("hello a shuge");
String jsonStr = JSONUtil.toJsonStr(dto);
System.out.println(jsonStr);
for (MultipartFile file : files) {
System.out.println(file.getOriginalFilename());
System.out.println(file.getName());
}
}
注意到,上面testFormData方法中的請求參數 使用的注解 是:@RequestPart
- 前端請求
function handleFileUpload(event) {
// 在這里構造上傳要用的fileList
const files = event.target.files;
if (files) {
for (let i = 0; i < files.length; i++) {
if (fileList.length < 20 && files[i].type.includes('image')) {
fileList.push(URL.createObjectURL(files[i]));
}
}
}
}
let formData = new FormData();
let request = {}; // json數據
// fileList是上面方法中fileList.push(URL.createObjectURL(files[i]));添加的元素
for (let key in fileList) {
formData.append('files', new Blob(fileList), 'files'); // 往formData中添加blob數據,這里涉及到append另外一個用法
}
// 注意下面:設置json數據時候,第三個參數指定此時set的數據是application/json類型
formData.set('dto', new Blob([JSON.stringify(request)], { type: 'application/json' }));
// 遍歷formData,打印到console
for (var pair of formData.entries()) {
console.log(pair[0] + ', ' + pair[1]);
}
UploaderApi.publishProduct(formData)
.then((res) => {
if (res.success) {
console.log("success");
} else {
console.log("failed");
}
})
.catch((err) => {
console.log("error");
});
http.interceptors.request.use(
(config) => {
// 在發送請求之前做些什么
if (config.method === 'post') {
// 這里處理上傳文件的請求
if (config.headers['Content-Type'] === 'multipart/form-data') {
const formData = new FormData();
// 構造新的formData(如果不需要添加reqId/stamp)那這步就可以省略了,直接config.data=formData就行
for (var pair of config.data.entries()) {
formData.append(pair[0], pair[1]);
}
formData.append('requestId', reqId);
formData.append('stamp', RequestUtil.generateTimestamp());
config.data = formData;
} else {
config.headers['Content-Type'] = 'application/json;charset=utf-8';
config.data = {
...config.data,
requestId: reqId,
stamp: RequestUtil.generateTimestamp(),
};
}
}
return config;
},
(error) => {
// 對請求錯誤做些什么
return Promise.reject(error);
},
);
請求參數實例

以上,就可以通過axios請求后端接口傳輸 json字符串+多文件
注意
涉及到的內容
- SpringBoot中@RequestPart的用法
- 前端FomrData.append與set的區別
- 通過將requestBody以contentType=application/json形式寫入formData中(里面其實是blob類型數據)
本文來自博客園,作者:你啊347,轉載請注明原文鏈接:http://www.rzrgm.cn/LinKinSJ/p/18154434

浙公網安備 33010602011771號