filesaver源码解读

网页实现文件下载可以使用成熟的类库FileSaver.js,其压缩后的大小也就2KB,引入的话也并不会对站点有多大的体积负担。同时我们也需要了解下该pkg的实现,这里就梳理下实现逻辑。

saveAs API

先看下API方法的参数情况,可以看到直接传入文件数据或者URL都可。

1
FileSaver saveAs(Blob/File/Url, optional DOMString filename, optional Object { autoBom })

处理流程

  1. 操作DOM创建a标签元素,由于a标签没有设置content,因此也不会出现在当前页面。
  2. a元素设置download属性,值即为指定的文件名。
  3. a元素设置rel值为noopener,设置的好处是性能和安全。
  4. 判断save存储的是不是字符串
    1. 是字符串的话,将会被视为URL,然后根据是否跨域决定是不是直接就可利用a标签直接下载保存,如果跨域,download属性不会work,因此必须XHR下载数据然后再作为blob进行下载保存,如果不跨域,a标签直接挂URL和download即可保证下载和保存。
    2. 非URL的话,blob数据直接作为a元素的href,触发a.click即可。

下载文件而不是打开文件

当我们直接URL下载文件时会发现浏览器会默认打开该文件,如果我们想改变这个行为有几个办法

  1. 同源文件下载的话,a标签方式下设置download属性即可,浏览器会视为设置了Content-Disposition:attachment,因此会作为附件进行下载。
  2. 非同源文件下载,download属性不会work,因此需要通过异步下载文件获得blob数据,之后构建a标签保存,或者是服务端返回设置Content-Disposition:attachment。

写在最后

done.