美文网首页
FileReader 读取文件流下载异常问题

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

作者: 鹤空 | 来源:发表于2022-04-22 11:08 被阅读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的合适时机

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/fomehrtx.html