通过blob实现文件下载的方法介绍

1,450 阅读2分钟

Blob 用作 URL

Blob 可以很容易的作为 <a><img> 或其他标签的 URL,多亏了 type 属性,我们也可以上传/下载 Blob 对象。

Blob URL

Blob URL/Object URL 是一种伪协议,允许 BlobFile 对象用作图像,下载二进制数据链接等的 URL 源。在浏览器中,我们使用 URL.createObjectURL 方法来创建 Blob URL,该方法接收一个 Blob 对象,并为其创建一个唯一的 URL,其形式为 blob:<origin>/<uuid>

浏览器内部为每个通过 URL.createObjectURL 生成的 URL 存储了一个 URL → Blob 映射。因此,此类 URL 较短,但可以访问 Blob。生成的 URL 仅在当前文档打开的状态下才有效。它允许引用 <img>、<a> 中的 Blob,但如果你访问的 Blob URL 不再存在,则会从浏览器中收到 404 错误。·

上述的 Blob URL 看似很不错,但实际上它也有副作用。虽然存储了 URL → Blob 的映射,但 Blob 本身仍驻留在内存中,浏览器无法释放它。映射在文档卸载时自动清除,因此 Blob 对象随后被释放。

但是,如果应用程序寿命很长,那不会很快发生。因此,如果我们创建一个 Blob URL,即使不再需要该 Blob,它也会存在内存中。

针对这个问题,我们可以调用 URL.revokeObjectURL(url) 方法,从内部映射中删除引用,从而允许删除 Blob(如果没有其他引用),并释放内存。接下来,我们来看一下 Blob 文件下载的具体示例。

Blob 文件下载的示例

eg1

download(fileName, blob) {
    const link = document.createElement("a");
    link.href = URL.createObjectURL(blob);
    link.download = fileName;
    link.click();
    link.remove();
    URL.revokeObjectURL(link.href);
};

eg2

download(fileName, blob) {
    const link = document.createElement("a");
    link.href = window.URL.createObjectURL(blob);
    link.style.display = 'none';
    link.download = fileName;
    document.body.appendChild(link)
    link.click();
    window.URL.revokeObjectURL(link.href);
    document.body.removeChild(link)
};

注意:文件下载后无法打开或者损坏请检查接口api是否添加:responseType: "blob"

export function sopExportPDF(id) {
  return request({
    url: "/tb/procedure/export/pdf/" + id,
    responseType: "blob",
    method: "get",
  });
}

通过接口跨域请求,动态创建a标签,以blob形式下载

思路:可以直接通过请求的方式拿到文件流,将文件流转为blob格式,再通过a标签的download属性下载

fetch('/upload/user.png').then((res) => {
  res.blob().then((blob) => {
    const blobUrl = window.URL.createObjectURL(blob);
    // 这里的文件名根据实际情况从响应头或者url里获取
    const filename = 'user.jpg';
    const a = document.createElement('a');
    a.href = blobUrl;
    a.download = filename;;
    a.click();
    window.URL.revokeObjectURL(blobUrl);
  });
});