post方法下载文件,需做哪些特殊处理

POST方法与GET方法下载的区别:

  • GET用于获取数据,POST用于提交数据。但文件下载通常属于获取资源,所以理想情况下应使用GET。然而,当参数较长或包含敏感信息时,使用POST更合适。

  • 对于文件下载,使用GET时,可以直接通过链接下载(例如window.open),不需要复杂的前端处理。

  • 使用POST时,不能直接用链接,必须通过表单提交或AJAX请求(如本例),然后将返回的文件通过Blob方式处理并触发下载。

导出流程​:通过Axios发送POST请求获取二进制Excel文件 → 创建临时URL → 模拟点击下载 → 清理资源

js 复制代码
    import axios from 'axios';
    
    <Button loading={loading} type="primary" onClick={exportStatistics}>下载报表</Button>
                
    const exportStatistics = async () => {
    const baseURL = `${window.location.protocol}//${process.conf.ip}${process.conf.nginx ? '/gateway' : ''}`
    const source = axios.CancelToken.source();
    try {
      if (!filterRef.current?.getFilterParam) {
        return;
      }
      const filterParams = filterRef.current.getFilterParam();
      setLoading(true);
      const payload = JSON.stringify({
        plantIdList: filterParams.plantIdList,
        indexList: filterParams.indexList,
      });
      const response = await axios.post(
        `${baseURL}/statistics/data/export`,
        payload,
        {
          headers: {
            'Content-Type': 'application/json',
            Accept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
          },
          responseType: 'blob', // 指定响应类型为二进制数据
          cancelToken: source.token,
          transformResponse: [data => data], // 禁用自动转换
        },
      );
      const blob = response.data ? response.data : response;
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `指标统计报表_${moment().format('YYYY-MM-DD HH:mm:ss')}.xlsx`;
      a.style.display = 'none';
      document.body.appendChild(a);
      a.click();
      setTimeout(() => {
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
        source.cancel(); // 取消请求令牌
      }, 100);
    } catch (error) {
      console.error('导出失败:', error);
    } finally {
      setLoading(false);
    }
  };

特殊处理及原因:

  1. responseType: 'blob'​:

    • 因为响应是二进制文件(Excel),所以需要将响应类型设置为blob,以便正确处理。
  2. transformResponse: [data => data]​:

    • 默认情况下,axios会根据响应类型转换数据,但这里我们不需要转换,所以覆盖默认转换器,直接返回原始数据。
  3. 创建临时URL和隐藏的a标签:

    • 由于我们无法直接保存来自AJAX请求的文件,因此将Blob数据转换为一个URL,并模拟点击一个下载链接来触发浏览器下载。
  4. 使用取消令牌:

    • 允许在组件卸载等情况下取消请求,避免内存泄漏和潜在的错误。
  5. setTimeout清理资源:

    • 在下载开始后移除临时创建的a标签和URL,释放资源。使用setTimeout是为了确保下载已经启动。
  6. 错误处理:

    • 捕获请求过程中可能出现的错误,例如网络问题或后端错误。
  7. 设置加载状态:

    • 在开始请求时设置加载状态,在请求结束后(无论成功或失败)清除状态,以提供用户反馈。
相关推荐
灵感__idea2 分钟前
Hello 算法:贪心的世界
前端·javascript·算法
killerbasd3 小时前
牧苏苏传 我不装了 4/7
前端·javascript·vue.js
橘子编程4 小时前
JavaScript与TypeScript终极指南
javascript·ubuntu·typescript
叫我一声阿雷吧5 小时前
JS 入门通关手册(45):浏览器渲染原理与重绘重排(性能优化核心,面试必考
javascript·前端面试·前端性能优化·浏览器渲染·浏览器渲染原理,重排重绘·reflow·repaint
大家的林语冰5 小时前
《前端周刊》尤大开源 Vite+ 全家桶,前端工业革命启动;尤大爆料 Void 云服务新产品,Vite 进军全栈开发;ECMA 源码映射规范......
前端·javascript·vue.js
jiayong235 小时前
第 8 课:开始引入组合式函数
前端·javascript·学习
天若有情6736 小时前
【C++原创开源】formort.h:一行头文件,实现比JS模板字符串更爽的链式拼接+响应式变量
开发语言·javascript·c++·git·github·开源项目·模版字符串
软件工程师文艺6 小时前
从0到1:Claude Code如何用React构建CLI应用
前端·react.js·前端框架
M ? A6 小时前
Vue 迁移 React 实战:VuReact 一键自动化转换方案
前端·vue.js·经验分享·react.js·开源·自动化·vureact
yuki_uix6 小时前
重排、重绘与合成——浏览器渲染性能的底层逻辑
前端·javascript·面试