dataURL 和 objectURL 有啥区别呢?<a href="http://www.alloyteam.com/wp-content/uploads/2015/03/s.png">
<img class="alignnone size-full wp-image-6433" alt="s" src="http://www.alloyteam.com/wp-content/uploads/2015/03/s.png" width="1012" height="526" />
</a> 刷新页面会发现 dataURL 不再变化,而 objectURL 会不断变化:
<a href="http://www.alloyteam.com/wp-content/uploads/2015/03/t.png"><img class="alignnone size-full wp-image-6434" alt="t" src="http://www.alloyteam.com/wp-content/uploads/2015/03/t.png" width="1015" height="526" /></a>
原因是,dataURL 创建的是实际的数据,而 objectURL 既然是 DOMString,依赖浏览器环境,
当这个页面一旦关闭(销毁),objectURL 将从内存中删除。
我们可以验证一下: 在浏览器地址栏输入 objectURL:
<a href="http://www.alloyteam.com/wp-content/uploads/2015/03/u.png"><img class="alignnone size-full wp-image-6435" alt="u" src="http://www.alloyteam.com/wp-content/uploads/2015/03/u.png" width="755" height="189" /></a>
当我们把创建 objectURL 的页面关闭后,再刷新会发现:
<a href="http://www.alloyteam.com/wp-content/uploads/2015/03/v.png"><img class="alignnone size-full wp-image-6436" alt="v" src="http://www.alloyteam.com/wp-content/uploads/2015/03/v.png" width="812" height="171" /></a>
数据不见了!因为浏览器页面关闭后回收了这段内存,那这段 blob: 引用的 DOMString 不再存在。
当然我们也可以手动调用 URL.revokeObjectURL() 的方式来回收。
(当多次调用 URL.createObjectURL 用完后,即时释放内存很重要)
在浏览器地址栏输入 dataURL, 发现 dataURL 是真实的数据,不会随页面关闭而消失:
<a href="http://www.alloyteam.com/wp-content/uploads/2015/03/w.png"><img class="alignnone size-full wp-image-6437" alt="w" src="http://www.alloyteam.com/wp-content/uploads/2015/03/w.png" width="1137" height="186" /></a>
dataURL 是真实的数据,可以用于对小图片进行编码等操作;
objectURL 可以将一个文件转化为 URL 的形式,让我们获得操作文件的能力。
<strong>服务器端与客户端下载文件</strong>
介绍了那么多 Blob, 是不是跑题了。。。
<strong>服务器端下载文件</strong>
服务器端下载文件主要有几步:
1. 根据请求将用户所需要的文件添加到一个临时文件夹 download/xxx
2. 将临时文件夹压缩 download/xxx.zip
3. 将压缩包返回 res.sendFile('download/xxx.zip')
4. 删除临时文件 fs.unlink('download/xxx.zip');
对于不同的用户,有不同的定制化要求时,生成临时文件夹也必须唯一,所以需要生成唯一的文件夹名。
压缩包生成后,立即删除临时文件夹,并在压缩包成功传回客户端后,立即删除压缩包文件,以节省硬盘空间。
<a href="http://www.alloyteam.com/wp-content/uploads/2015/03/x.png"><img class="alignnone size-full wp-image-6438" alt="x" src="http://www.alloyteam.com/wp-content/uploads/2015/03/x.png" width="425" height="86" /></a>
在这里对每个定制化的请求返回一个压缩包响应后,立即删除了临时文件。
<a href="http://www.alloyteam.com/wp-content/uploads/2015/03/y.png"><img class="alignnone size-full wp-image-6439" alt="y" src="http://www.alloyteam.com/wp-content/uploads/2015/03/y.png" width="865" height="597" /></a>
还有一种做法是对压缩包进行缓存,若发现缓存中存在对应的压缩包,则不再新建。
前者可以立即释放硬盘空间,后者则可以节省计算,各有利弊。
<strong>浏览器端下载文件</strong>
浏览器端下载文件主要有几步:
1. 使用 AJAX 去下载所需要的文件
2. 使用 Blob 对象对文件内容进行存储
3. 使用 JSZip.js 或其他 zip 类库进行压缩
4. 使用 FileSaver.js 或其他 file 接口保存文件
<a href="http://www.alloyteam.com/wp-content/uploads/2015/03/z.png"><img class="alignnone size-full wp-image-6440" alt="z" src="http://www.alloyteam.com/wp-content/uploads/2015/03/z.png" width="865" height="229" /></a>
ajax 异步下载文件,如何得知所有文件下载完成呢? 可以自己维护一个计数器,或者使用 Promise 吧!
<a href="http://www.alloyteam.com/wp-content/uploads/2015/03/z-a.png"><img class="alignnone size-full wp-image-6441" alt="z-a" src="http://www.alloyteam.com/wp-content/uploads/2015/03/z-a.png" width="790" height="590" /></a>
我这里使用了以下优秀类库
- [jsZip](https://stuk.github.io/jszip/) 用于在浏览器端压缩文件
- [FileSaver](https://github.com/eligrey/FileSaver.js) 用于将文件保存到本地
- [bluebird](https://github.com/petkaantonov/bluebird) 用于控制异步 AJAX 获取文件
<strong>服务器端与浏览器端下载文件的对比</strong>
<a href="http://www.alloyteam.com/wp-content/uploads/2015/03/z-b.png"><img class="alignnone size-full wp-image-6442" alt="z-b" src="http://www.alloyteam.com/wp-content/uploads/2015/03/z-b.png" width="862" height="473" />
</a>