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

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

相关推荐
abcnull2 小时前
用javaparser做精准测试
java·ast·静态代码分析·精准测试·javaparser
叶小鸡2 小时前
Java 篇-项目实战-苍穹外卖-笔记汇总
java·开发语言·笔记
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题】【Java基础篇】第22题:HashMap 和 HashSet 有哪些区别
java·开发语言·哈希算法·散列表·hash
juniperhan3 小时前
Flink 系列第21篇:Flink SQL 函数与 UDF 全解读:类型推导、开发要点与 Module 扩展
java·大数据·数据仓库·分布式·sql·flink
ID_180079054733 小时前
Python 实现亚马逊商品详情 API 数据准确性校验(极简可用 + JSON 参考)
java·python·json
devpotato3 小时前
Spring Boot mTLS 报 `keystore password was incorrect`:不一定是密码错了
spring boot·tls·pkcs12·mtls
c++之路3 小时前
C++23概述
java·c++·c++23
专注API从业者4 小时前
Open Claw 京东商品监控选品实战:一键抓取、实时监控、高效选品
java·服务器·数据库
摇滚侠4 小时前
DBeaver 导入数据库 导入 SQL 文件 MySQL 备份恢复
java·数据库·mysql
keep one's resolveY5 小时前
SpringBoot实现重试机制的四种方案
java·spring boot·后端