You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Axios场景下如何解决JS Blob触发文件重复下载问题

问题场景
  • 调用后端微服务API端点,接口返回HTML文件作为响应数据,技术栈为ReactJS + Axios,可正常获取响应结果
  • 在请求回调的.then代码块中,通过JavaScript Blob处理响应数据,实现本地HTML文件保存逻辑:将接口返回数据转换为携带自定义文件名的可下载链接,执行link.click()时自动触发文件下载
  • 当前异常:浏览器会将同一个HTML文件重复下载两次,预期效果为文件仅触发一次下载,无重复下载问题

原有实现代码如下:

const callAPI = () => {
  Axios.post(api_endpoint, bodyArgs)
    .then((response) => {
      const url = window.URL.createObjectURL(new Blob([response.data]));
      const link = document.createElement("a");
      link.href = url;
      link.setAttribute("download", `${company}_${startDate}_${endDate}.html`);
      document.body.appendChild(link);
      link.click();
    })
    .catch(function (error) {
      console.log(error);
      alert(
        "Sorry, there was an error processing your request. Please check the dates of your report and try again!"
      );
    });
};
问题根因

该问题不属于浏览器兼容问题,核心是代码逻辑存在遗漏,同时存在高频触发的场景问题:

  1. 临时DOM节点与Blob资源未清理:创建的临时a标签挂载到body后,触发点击就结束逻辑,没有移除临时节点、也没有释放createObjectURL生成的临时Blob地址,部分浏览器在DOM更新、资源扫描阶段会重复触发下载行为
  2. 事件重复触发:如果callAPI绑定在表单提交按钮上、或者同时绑定了React合成事件与原生DOM事件,会导致函数被执行两次,触发两次下载
  3. React严格模式影响:开发环境下React StrictMode会重复执行回调函数做副作用检测,也可能导致下载触发两次,该问题仅在开发环境出现
修复方案
  1. 补全资源清理逻辑,触发下载后立即移除临时a标签、释放Blob URL,同时给Axios请求加上responseType: 'blob'配置,避免数据解析异常
  2. 排查事件绑定逻辑,若绑定在表单提交事件上,添加e.preventDefault()阻止表单默认提交行为
  3. 若为React严格模式导致的开发环境重复触发,可暂时关闭严格模式验证,生产环境构建后该问题会自动消失

修正后的可运行代码:

const callAPI = () => {
  // 补充responseType配置,确保返回的是Blob格式数据
  Axios.post(api_endpoint, bodyArgs, { responseType: 'blob' })
    .then((response) => {
      const blob = new Blob([response.data], { type: 'text/html' });
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement("a");
      link.href = url;
      link.setAttribute("download", `${company}_${startDate}_${endDate}.html`);
      // 隐藏临时链接避免影响页面布局
      link.style.display = 'none';
      document.body.appendChild(link);
      link.click();
      // 触发下载后立即清理临时资源
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);
    })
    .catch(function (error) {
      console.log(error);
      alert(
        "Sorry, there was an error processing your request. Please check the dates of your report and try again!"
      );
    });
};

内容的提问来源于stack exchange,提问作者rockyswdev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 00:24:25