1、前端代碼
const service = axios.create({baseURL: "http://192.168.2.200:8080/api",timeout: 180000
})// 響應攔截
service.interceptors.response.use(async response => {if(response){// 請求時設置返回blob, 但是實際上可能返回的是json的情況if (response.data instanceof Blob) {if (!response.headers['content-type']?.includes('application/json')) {let a = document.createElement("a");a.setAttribute("href", URL.createObjectURL(response.data));a.setAttribute("download", decodeURI(response.headers['filename']));a.setAttribute("target", "_blank");a.click()return null}// 將后臺返回的內容轉成文本response.data = JSON.parse(await (response.data).text())}return response.data
}, err)
?主要是:if (response.data instanceof Blob)? 判斷是否是 Blob 對象,
否則使用:response.data = JSON.parse(await (response.data).text()) 將后臺返回的內容轉成 文本 返回
const formData = new FormData();
formData.append('id', 1);
formData.append('file', _file.file);const config = {headers: { 'Content-Type': 'multipart/form-data' },responseType: 'blob'
}axios.post('/file/upload', formData, config).then((res: any) => {if (res != null && res.code == 200) {alert("上傳成功");} else {alert("上傳失敗");}})
主要是:responseType: 'blob'
2、后端代碼
@Controller
@RequestMapping("api/file")
public class FileController {@PostMapping("upload")public void upload(MultipartFile file, HttpServletResponse response) {// 緩存文件String tmpDirPath = FileUtil.getTmpDirPath();// 上傳文件名String originalFilename = file.getOriginalFilename();String targetFile = tmpDirPath + File.separator + originalFilename;FileUtil.writeFromStream(file.getInputStream(), targetFile);// 解析文件boolean result = parseFile(targetFile);if(!result){// 解析失敗,返回失敗文件InputStream in = new FileInputStream(targetFile);String filename = "解析失敗_" + System.currentTimeMillis() + "_" + originalFilename;// 告訴瀏覽器輸出內容為流response.setContentType("application/octet-stream;charset=utf-8");// 前端下載時的文件名response.setHeader("filename", URLEncoder.encode(filename, "UTF-8"));// 響應報頭 指示哪些報頭可以 公開 為通過列出他們的名字的響應的一部分。要公開多個自定義標題,可以用逗號分隔// 默認情況下,只顯示6個簡單的響應頭 Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragmaresponse.setHeader("Access-Control-Expose-Headers", "filename");IOUtils.copy(in, response.getOutputStream());} else {response.setContentType("application/json;charset=utf-8");JSONObject jsonObject = new JSONObject();jsonObject.put("code", 200);jsonObject.put("message", "成功");response.getWriter().write(jsonObject.toJSONString());}// 刪除臨時文件FileUtil.del(targetFile);}}
需要注意的是:response.setHeader("Access-Control-Expose-Headers", "filename");
否則前端讀取不到?response.headers['filename'] 的值