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

如何通过Axios实现浏览器下载管理器实时显示大文件进度?

实现浏览器原生下载进度显示的解决方案

是的,完全可以通过让浏览器直接处理下载请求来实现像Windows ISO下载那样的原生进度显示,而不需要先把整个文件下载到本地临时存储。

问题根源

你当前的客户端代码是先通过Axios把整个文件下载到内存(转为Blob),再通过创建链接触发下载。这时候浏览器的下载管理器只能看到最后一步把Blob保存到本地的操作,无法显示从服务器下载文件的真实进度。

服务器端代码检查(基本无需修改)

你的Java服务器代码已经在做流式传输了:使用IOUtils.copy把输入流直接写到响应输出流,同时设置了Content-Length头。这部分是正确的,但有两个小优化点:

  1. 如果文件大小可能超过2GB,把response.setContentLength((int) exportedData.size());改为response.setContentLengthLong(exportedData.size());(因为int类型最大只能表示2GB左右的数值)。
  2. 可以指定一个合理的缓冲区大小来提升传输效率,比如:
IOUtils.copy(exportedData.inputStream(), response.getOutputStream(), 8192); // 使用8KB缓冲区

客户端解决方案

根据你的API是否需要自定义请求头(比如认证Token),分两种情况处理:

情况1:无需自定义请求头(最简单)

直接创建指向下载URL的链接并触发点击,浏览器会原生处理下载并显示进度:

const a = document.createElement('a');
a.href = url; // 你之前传给Axios的下载URL
a.click();
a.remove();

服务器返回的Content-Disposition头会自动指定文件名,不需要手动设置download属性。

情况2:需要自定义请求头(比如认证Token)

常规链接无法携带自定义请求头,这时候可以采用生成临时签名URL的方案:

  1. 服务器端新增接口:创建一个接口,接收认证信息后返回一个临时的、无需额外认证的下载URL(这个URL可以设置有效期,比如5分钟)。
  2. 客户端流程:先请求这个签名URL,再用它触发原生下载:
// 1. 获取临时签名URL
const signedUrlResp = await taxGuruAxios.get('/api/get-signed-download-url', {
  params: { taskId: yourTaskId }
});
const signedUrl = signedUrlResp.data;

// 2. 触发原生下载
const a = document.createElement('a');
a.href = signedUrl;
a.click();
a.remove();

这种方式既保留了认证安全,又能让浏览器原生处理下载进度。

为什么之前的方式不行?

Axios下载Blob的过程是在JavaScript层面完成的,浏览器的下载管理器无法感知这个过程。只有当请求由浏览器直接发起时,才能触发原生的进度跟踪和下载管理。

内容的提问来源于stack exchange,提问作者Adam Ostrožlík

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 11:42:56