如何使用浏览器自带的下载进行分片传输?

想请问下,目前有一个前端下载文件的需求,之前用axios实现过了分片传输下载,但是有一个问题在于是各个分片下载完成并合并之后,才在浏览器的下载栏中显示。而一般的下载则是可以在浏览器的下载栏中显示的,看了网上很多博客和教程都没有使用浏览器自带下载功能实现分片传输的方法。想请问下这是有可能实现的吗?
bb6e038e5a8b67c55e794e3941ca5cb7.png

1.实现过正常的直接用axios实现的分片传输。
2.使用浏览器自带的下载一般似乎是通过下面的步骤进行的:

function triggerDownload(url, filename) {
  const link = document.createElement('a');
  const downloadUrl = `${url}?token=${encodeURIComponent(getToken())}`;
  link.href = downloadUrl;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

/**
 * 使用浏览器默认的范围请求下载文件
 * @param {string} filename 文件名
 */
export function downloadFilesDefault(filename) {
  // 构建下载URL,包含认证信息或必要的参数
  const downloadUrl = `${window.g.BASE_URL}compilation/rangeDownload`;

  triggerDownload(downloadUrl, filename);
}

但是这种一开始就点击标签进行下载的,怎么实现多次请求的分片传输呢?

还有一个额外的问题想请教各位~
因为之前没怎么关注过下载这部分,所以比较疑惑如果浏览器本身自带了下载的功能,包括断点重试之类的话,那么一般企业中的实际应用场景是怎么样的呢?
使用浏览器本身来下载文件的时候多吗?
什么时候会考虑使用api自定义实现各种下载方式呢?

阅读 1.4k
1 个回答

如果只考虑 Chromium 内核的浏览器,并且可以得到用户支持(毕竟支持网站直接读写文件是一件很危险的事情)的话,可以考虑 FileSystem
使用 FileSystem ,JS 就可以以 stream 的形式向文件尾部追加内容,而fetch API 恰好支持使用 pipeTo 读取,也就是可以在请求数据的同时,向文件里写入:

async function writeURLToFile(fileHandle, url) {
  // Create a FileSystemWritableFileStream to write to.
  const writable = await fileHandle.createWritable();
  // Make an HTTP request for the contents.
  const response = await fetch(url);
  // Stream the response into the file.
  await response.body.pipeTo(writable);
  // pipeTo() closes the destination pipe by default, no need to close it.
}
chrome.cn 提供的例子,这里展示的是向文件写入流,分片应该就是等上一个流关闭之后,请求下一个片段并继续写入了。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏