Skip to content

下载文件进度

​ 在网页中,有文件下载功能时,我们时常需要通过文件总大小以及当前下载大小计算出下载百分比。但纯前端无法获得目标文件的总大小,此时我们需要让后端的响应报文中配置响应头部Content-Length字段,Content-Length 字段可以和 XHR 配合,实现下载进度这个功能。

关键点:后端需要给下载的文件配置响应头部Content-Length,前端需要监听onprogress事件。

后端

​ 后端需要在响应数据的同时配置Content-Length字段即可,在 node 中可以通过fs.stat获取文件信息。文件读取最好使用流式+管道的方式,这样节省内存开销和带宽占用。

js
// 获取文件大小
const stats = fs.statSync("./a.txt");
// 配置响应头部
res.setHeader("Content-Length", String(stats.size));
// 获取文件大小
const stats = fs.statSync("./a.txt");
// 配置响应头部
res.setHeader("Content-Length", String(stats.size));

前端

​ 通过 XHR 实例的 onprogress 事件,监听传输过程

​ e.total 是本次传输的总大小,后端必须响应 Content-Length 字段,否则一致都是 0。

js
const box = document.querySelector(".box");
const xhr = new XMLHttpRequest();
xhr.open("get", "/01.mp4");
xhr.send();
xhr.onprogress = (e) => {
  // e.loaded是当前加载了多少了
  // e.total是总大小,后端必须响应Content-Length字段,否则一直都是0
  box.innerText = `${((e.loaded / e.total) * 100).toFixed(2)}%`;
};
xhr.onload = (e) => {
  console.log(e);
};
const box = document.querySelector(".box");
const xhr = new XMLHttpRequest();
xhr.open("get", "/01.mp4");
xhr.send();
xhr.onprogress = (e) => {
  // e.loaded是当前加载了多少了
  // e.total是总大小,后端必须响应Content-Length字段,否则一直都是0
  box.innerText = `${((e.loaded / e.total) * 100).toFixed(2)}%`;
};
xhr.onload = (e) => {
  console.log(e);
};

参考

  1. https://juejin.cn/post/6955011872298893319