FileReader 读取文件流下载异常问题

2022-04-22  本文已影响0人  鹤空

场景

服务器返回文件流,用于下载。前端需要自定义下载文件名,因此需要使用javascript处理文件流blob

异常代码

const reader = new FileReader();
reader.readAsDataURL(res);
reader.onload = (e) => {
       // 转换完成,创建一个a标签用于下载
       if (e.target) {
         const a = document.createElement('a');
         a.download = options.fileName || 'download';
         a.href = e.target.result;
         document.body.appendChild(a);
         a.click();
         a.remove();
       }
}

文件下载时,windows chrome提示如下


image.png

原因分析

reader.readAsDataURLblob转换为Base64赋值给a标签, a 标签长度有限制,会被截断,因此地址异常

解决

使用URL.createObjectURL(res)blob转换为一个对象URL用于下载。

正常代码

 const url = URL.createObjectURL(res);
 const a = document.createElement('a');
 a.download = options.fileName || 'download';
 a.href = url;
 a.onclick = () => {
   requestAnimationFrame(() => {
     URL.revokeObjectURL(url);
   })
 }
 document.body.appendChild(a);
 a.click();
 a.remove();

内存管理

在每次调用 createObjectURL() 方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。当不再需要这些 URL 对象时,每个对象必须通过调用 [URL.revokeObjectURL()](https://developer.mozilla.org/zh-CN/docs/Web/API/URL/revokeObjectURL) 方法来释放。

浏览器在 document 卸载的时候,会自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。

延伸

  1. a标签最大长度 image
  2. Base64 位数和文件大小关系 https://www.yuque.com/hekong/unveqo/vv0yop

  3. 验证释放ObjectURl的合适时机

上一篇下一篇

猜你喜欢

热点阅读