1、前端代码
javascript
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())**将后台返回的内容转成 文本 返回
javascript
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、后端代码
java
@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、Pragma
response.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']**的值