You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React中使用Axios下载文件并实现进度条的方案咨询

实现下载进度条的解决方案

嘿,这个问题我太熟悉了!你当前的代码是直接等待整个Blob下载完成后才触发下载动作,用户完全看不到中间状态——确实很影响体验。好在axios提供了onDownloadProgress回调,专门用来监听下载进度,咱们可以利用它轻松实现进度条功能。

步骤1:添加进度跟踪状态

首先在你的组件状态里新增一个变量,用来实时记录下载进度,初始值设为0:

this.state = {
  downloading: false,
  downloadProgress: 0 // 新增进度状态
};

步骤2:在axios请求中加入进度监听逻辑

修改你的axios配置,添加onDownloadProgress回调。这个回调会在下载过程中持续触发,通过progressEvent可以拿到已加载大小和文件总大小,从而计算出当前下载进度:

await axios({
  url: sUrl,
  method: "GET",
  responseType: "blob",
  // 新增下载进度监听
  onDownloadProgress: (progressEvent) => {
    // 检查服务器是否返回了文件总大小(依赖Content-Length响应头)
    if (progressEvent.lengthComputable) {
      const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
      this.setState({ downloadProgress: percentCompleted });
    }
  }
})
.then(response => {
  const url = window.URL.createObjectURL(new Blob([response.data]));
  const link = document.createElement("a");
  link.href = url;
  link.setAttribute("download", fname);
  document.body.appendChild(link);
  link.click();
  // 下载完成后重置进度状态
  this.setState({ downloading: false, downloadProgress: 0 });
})
.catch(error => {
  // 下载出错时也重置进度状态
  this.setState({ downloading: false, downloadProgress: 0 });
  message.warn("Errore: " + error.message);
  return [];
});

步骤3:渲染进度条

在组件的渲染部分,根据downloading状态显示进度条。这里我写了一个简单的原生进度条示例,你也可以用Ant Design的Progress组件之类的UI组件来美化:

{this.state.downloading && (
  <div style={{ margin: '16px 0' }}>
    <p>正在下载:{this.state.downloadProgress}%</p>
    <div style={{ 
      width: '100%', 
      height: '8px', 
      borderRadius: '4px', 
      backgroundColor: '#f0f0f0',
      overflow: 'hidden'
    }}>
      <div 
        style={{ 
          width: `${this.state.downloadProgress}%`, 
          height: '100%', 
          backgroundColor: '#1890ff',
          transition: 'width 0.3s ease'
        }}
      />
    </div>
  </div>
)}

关键注意事项

  • 服务器依赖:精确进度计算需要服务器返回Content-Length响应头,如果服务器没返回这个头,progressEvent.lengthComputable会是false,这时候只能显示“正在下载中”的加载状态,没法展示精确进度。
  • 跨域场景:如果是跨域下载,需要确保服务器的CORS配置允许暴露Content-Length头(在响应头里添加Access-Control-Expose-Headers: Content-Length),否则前端拿不到文件总大小。

这样用户就能在下载过程中实时看到进度变化,再也不会一脸懵不知道网站在后台忙活啥了😉

内容的提问来源于stack exchange,提问作者Luca F.

火山引擎 最新活动