免费申请网站永久域名,网站如何备案 流程图,最新网站建设合同,类似58的推广平台有哪些平台本文简介
点赞 关注 收藏 学会了 本文介绍一个能让前端优雅下载大文件的工具#xff1a;StreamSaver.js
⚡️ StreamSaver.js GitHub地址⚡️ 官方案例 StreamSaver.js 可用于实现在Web浏览器中直接将大文件流式传输到用户设备的功能。
传统的下载方式可能导致大文件的加…本文简介
点赞 关注 收藏 学会了 本文介绍一个能让前端优雅下载大文件的工具StreamSaver.js
⚡️ StreamSaver.js GitHub地址⚡️ 官方案例 StreamSaver.js 可用于实现在Web浏览器中直接将大文件流式传输到用户设备的功能。
传统的下载方式可能导致大文件的加载时间较长或造成内存占用过大的问题使用 a 标签打开新页面下载文件遇到 .txt 或者 .mp4 之类的文件可能就直接在页面展示了不会触发下载功能。而 StreamSaver.js 则通过流式下载的方式解决了这些问题。
StreamSaver.js 将大文件拆分成小块并在下载过程中逐块传输到硬盘从而降低内存占用和提高下载速度。 环境准备
要学习 StreamSaver.js 首先要准备一份或者多份可下载的文件。
你可以使用网络上的文件资源但这需要你自己去找。
你也可以在自己的电脑运行个服务把文件资源丢进去即可。 如果你用脚手架创建项目比如vue或者react之类的项目也可以把文件放在静态资源目录里。
比如用 vite 创建一个 Vue 项目然后在 public 目录下创建一个 test.txt 文件。项目运行起来在浏览器访问 http://localhost:端口号/public/test.txt 就能查看到这个文件内容。 安装 StreamSaver.js
可以使用 CDN 或者 npm 安装 StreamSaver.js。
本文使用 CDN 的方式讲解。 CDN
打开 StreamSaver.js的仓库。 把 StreamSaver.js 文件下载到你项目里引入即可。
script src../StreamSaver.js/script npm
⚡️StreamSaver npm地址 使用以下命令下载 StreamSaver 到项目里
npm i streamsaver
然后在要使用的地方引入即可。
import streamSaver from streamsaver 起步
起步阶段我们先试试如何下载一个 .txt 文件。
如果我们要下载一些浏览器读不懂的文件我们可以使用 a标签在新窗口打开链接也可以使用 windows.open(url) 的方式打开新窗口进行下载。
但如果这个文件浏览器是读得懂的比如 .txt 文件那浏览器就不会执行下载而是会直接在页面中把文件内容展示出来。
此时就可以使用 StreamSaver.js 来解决这个问题。
使用 StreamSaver.js 下载文件的大概流程是这样的为了方便理解我用一些不专业的术语进行描述
创建一个文件该文件支持写入操作。streamSaver.createWriteStream(文件名.后缀)。使用 fetch 方法访问文件的url将内容一点点的放到 StreamSaver 创建的文件里。监听文件内容是否读取完整读取完就执行“保存并关闭文件”的操作。 根据上面的指引编写代码
!-- 下载按钮 --
button iddownload下载/button!-- 引入StreamSaver.js --
script src../StreamSaver.js/script
script// 监听按钮点击事件点击就下载文件download.onclick () {// 【步骤1】创建一个文件该文件支持写入操作const fileStream streamSaver.createWriteStream(test.txt) // 这里传入的是下载后的文件名这个名字可以自定义// 【步骤2】使用 fetch 方法访问文件的url将内容一点点的放到 StreamSaver 创建的文件里fetch(http://localhost:9988/public/test.txt).then(res {const readableStream res.bodyif (window.WritableStream readableStream.pipeTo) {return readableStream.pipeTo(fileStream).then(() console.log(完成写入))}// 【步骤3】监听文件内容是否读取完整读取完就执行“保存并关闭文件”的操作。window.writer fileStream.getWriter()const reader res.body.getReader()const pump () reader.read().then(res res.done? writer.close(): writer.write(res.value).then(pump))pump()})}
/script
大概就是这样子了。 提示
如果遇到提示跨域的问题可以配置 mitm 指向 mitm.html。
mitm.html 在 StreamSaver.js仓库 里可以获取到。 可以把 mitm.html 放到你服务器再配置。
streamSaver.mitm https://你的服务器地址/mitm.html 打包下载 zip
如果想将多个文件打包成zip下载到本地可以将 StreamSaver.js 和 zip-stream.js 结合在一起使用。
zip-stream.js 在 StreamSaver.js 的仓库里有。 zip-stream.js 在 /examples 目录里。 使用 npm 安装 streamsaver 也能在 /examples 目录下找到 zip-stream.js直接引入即可。
import node_modules/streamsaver/examples/zip-stream.js 如果使用 CDN 的方式就直接用 script srczip-stream.js/script 引入即可。 打包zip下载的步骤
创建下载后的文件名和文件格式。使用 zip-stream 创建一个 ZIP 实例用来不断接收要下载的文件。所有文件下载完成就执行 close() 方法将所有文件真正打包成一个 zip。 button iddownload下载/buttonscript src../StreamSaver.js/script
script srczip-stream.js/script
script// 要下载的文件地址列表let urls [{fileName: test.txt,url: http://localhost:9988/public/test.txt,},{fileName: test.csv,url: http://localhost:9988/public/test.csv,}]download.onclick () {// 【步骤1】const fileStream streamSaver.createWriteStream(test.zip)// 【步骤2】const readableZipStream new ZIP({async pull(ctrl) {for (let i 0; i urls.length; i) {const res await fetch(urls[i].url)const stream () res.bodyconst name urls[i].fileNamectrl.enqueue({ name, stream }) // 不断接收要下载的文件}// 【步骤3】ctrl.close()}})if (window.WritableStream readableZipStream.pipeTo) {return readableZipStream.pipeTo(fileStream).then(() console.log(下载完了))}}/script
点击下载按钮后的效果 这个例子准备了 .csv 和 .txt 文件。下载时会合并成 .zip解压后能看到里面的所有文件都是正常能打开的 。 合成文件再下载
在这个例子中我要将2个 .csv 文件合并成1个再下载。
我准备了两个 .csv 文件test1.csv 和 test2.csv它们的内容分别长这个样子。 我要将它们合并成这样子 在合并文件之前我们首先要清楚这个文件的内容是如何组成的。
在 Excel 中打开 .csv 的每个单元格的内容转换成文本形式的话是用逗号分隔。 如果要合并多个 .csv 文件只需监听到每个 .csv 下载完成然后再拼接一个 \n 换行再下载下一个 .csv 文件即可。 整理一下就是以下几个步骤
拿到一组下载地址把它们转存到一个迭代器里。递归执行迭代器如果迭代器里还有内容就使用 fetch 请求数据。如果迭代器没内容了使用 writer.close() 关闭文件写入。 该功能写成真正的代码如下所示
button iddownload οnclickdown()下载/buttonscript src../StreamSaver.js/script
script// 编码转换方法let encode TextEncoder.prototype.encode.bind(new TextEncoder)// 准备好要下载的链接const urls [http://localhost:9988/public/test1.csv,http://localhost:9988/public/test2.csv]// 迭代器数据let urlsIter null// 写入方法放到全局中保存let writer null// 下载按钮点击事件function down() {// 创建一个下载管道并将下载后的文件命名为 newTest.csvconst fileStream streamSaver.createWriteStream(newTest.csv)// 创建写入方法writer fileStream.getWriter()// 将要下载的链接转换成迭代器urlsIter urls[Symbol.iterator]()// 开始执行循环下载forDown()}// 循环下载的方法async function forDown() {// 获取迭代器最新一条数据let urlIter urlsIter.next()// 如果迭代器没数据执行写入完成操作并停止递归if (urlIter.done) {writer.close()return}// 迭代器有内容时执行请求操作await fetch(urlIter.value).then(res {// 通过请求文件url获取到的数据const readableStream res.bodyif (window.WritableStream readableStream.pipeTo) {const reader readableStream.getReader()// 讲获取到的每一包写入文件里const pump () {return reader.read().then(readRes {if (readRes.done) { // 当前文件读取完成后执行// 文件读取完成后换行writer.write(encode(\n))// 执行请求下一个文件forDown()} else { // 文件读取过程执行// 一包包写入writer.write(readRes.value).then(pump)}})}pump()}})}
/script
这个案例稍微复杂一丢丢建议跟着手敲一遍。 推荐阅读
除了本文所讲内容外StreamSaver.js 的仓库还有好几个实用的例子有需要的工友可以去看看。 《前端中文汉字转拼音》
《提升日期处理效率day.js 实战经验分享》
《眨个眼就学会了Pixi.js》
《OpenLayers.js 入门教程打造互动地图的入门指南》
《物理世界的互动之旅Matter.js入门指南》
《p5.js 光速入门》 点赞 关注 收藏 学会了 代码仓库