vue 文件下载两种方式streamSaver FileSaver

2,345 阅读1分钟

文件下载的时候内容过大 会造出浏览器崩溃,不同浏览器内存不同,但是到底一定的内存浏览器崩掉。axios下载的时候通过blob文件流下载,是通过把流下载到浏览器中然后从浏览器下载的,所以会造出以上情况,目前这个方式是使用fetch—+streamSaver插件 官方文档github.com/jimmywartin… 有使用方式 但是用的时候本地是可以的 生成环境的下载也是可以的但是这个对视频的预览有影响 没查到是什么原因 然后换了下面的写法 但是感觉也没差 不过目前都是正常的 然后这个插件有个缺点就是点击下载会有一个弹框,是这个插件内涵的一个安全考虑的 相当于浏览器拦截重方向,目前没查找到如果隐藏,觉得不好看的话 可以再谷歌浏览器的安全里面设置一下 如果后续有浏览者知道怎么出来 欢迎留言

FileSaver.js

网上常见的方式是 FileSaver.js + JSZIP 采用的是将先将文件下载的本地,然后该插件将客户端内存存储中的文件给导出并打包.但是这插件有很大的限制就是文件大小限制,谷歌浏览器都只能2GB以下,其他更低。因为浏览器的内存非常有限,所以就不考虑了
import { saveAs } from "file-saver"; // axios

          //   .get(`${environment.uploadurl}/download3/file`, {

          //     headers: { "Content-Type": "application/pdf" },

          //     params: params,

          //     responseType: "arraybuffer",

          //   })

          //   .then((respData) => {

          //     var blob = new Blob([respData.data], {

          //       type: typeList.mimeType[extname(fileName)],

          //     });

          //     saveAs(blob,fileName)

          //     // 下载改为使用saveAs下载这样容量更大

          //     // download(URL.createObjectURL(blob), fileName);

          //   });

StreamSaver.js

StreamSaver.js采用直接创建一个可写流到文件系统的方法。而不是将数据保存在客户端存储或内存中,对于在浏览器操作流的资料大家可以看到一下这篇文章以流的角度处理网络请求 对于需要保存在客户端创建的大量数据的操作来说是完美的解决方案。

有了读写流的能力,还需要解决的一个问题就是如何维持一个持续的通道,保证能够一边在下载,一边把下载的东西写到本地。制造一个(不存在的)下载链接,然后用 Service Worker 去拦截对这个下载链接的请求,持续往这下载链接写入文件流就可以了。

Service worker 的概念

1.Service worker是一个注册在指定源和路径下的事件驱动worker。它采用JavaScript控制关联的页面或者网站,拦截并修改访问和资源请求,细粒度地缓存资源。你可以完全控制应用在特定情形(最常见的情形是网络不可用)下的表现。

2.Service worker运行在worker上下文,因此它不能访问DOM。相对于驱动应用的主JavaScript线程,它运行在其他线程中,所以不会造成阻塞。它设计为完全异步,同步API(如XHR和localStorage)不能在service worker中使用。

3.出于安全考量,Service workers只能由HTTPS承载,毕竟修改网络请求的能力暴露给中间人攻击会非常危险。在Firefox浏览器的用户隐私模式,Service Worker不可用。 npm i streamSaver import streamSaver from 'streamSaver' qa.1r1g.com/sf/ask/4102…
c

               // 文件下载-触发

                const handleDownload = (fileInfo) => {

                  downloadFileFromServer(fileInfo.name);

                };

                function getProgress(relativePath, fileName, url) {

                  console.log(url, "url");

                  fetch(`${environment.downloadPath}/${relativePath}`, {

                    method: "GET",

                  })

                    .then((response) => {

                      console.log("response", response);

                      if (!window.WritableStream) {

                        streamSaver.WritableStream = WritableStream;

                        window.WritableStream = WritableStream;

                      }




                      const fileStream = streamSaver.createWriteStream(fileName, {

                        size: response.headers.get("content-length"),

                      });

                      const readableStream = response.body;




                      // More optimized

                      if (readableStream.pipeTo) {

                        return readableStream.pipeTo(fileStream);

                      }




                      window.writer = fileStream.getWriter();




                      const reader = response.body.getReader();

                      const pump = () =>

                        reader

                          .read()

                          .then((res) =>

                            res.done ? writer.close() :                                   writer.write(res.value).then(pump)

                          );




                      pump();

                    })

                    .catch((error) => {

                      console.log(error);

                    });

                }