axios同一个接口,同时接收 文件 或者 数据

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、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'] 的值

你可能感兴趣的:(编程,项目经验,java,vue.js,spring,boot)