Angular 集成 StreamSaver 大文件下载
应用场景:
实现目标: 在网页端实现大文件(文件大小 >= 2 G) 断点续传
实际方案: 发送多次请求, 每次请求一部分文件数据, 然后通过续写将文件数据全部写入.
难点: 无法实现文件续写, 最后采用 StreamSaver 来解决这个问题.
1. 首先从 git hub 将 StreamSaver 拉取下来.
StreamSaver gitHub 项目地址: GitHub - jimmywarting/StreamSaver.js: StreamSaver writes stream to the filesystem directly asynchronous
(这里推荐使用将 StreamSaver.js 文件直接放到项目中, 因为 StreamSaver 的实现需要借助已授信 https 服务器,
如果不配置自己的 https 服务器, 会访问 StreamSaver.js 默认已授信 https 服务器, 来实现下载功能
如果使用的是自签名的 https 服务器, 需要将证书安装在用户电脑或用户浏览器端进行一些配置才可正常使用, 稍后会讲到)
2.将 js 库导入 Angular 项目, 能在 ts 文件中调用 js 库的函数, 变量.
2.1 将 StreamSaver.js 文件放在 Angular 项目 assets\utils-js 目录下
2.2 然后在 index.html 的 head 标签中添加脚本, 如下:
<head> ... 其他代码 <script type="text/javascript" src="assets/utils-js/StreamSaver.js"></script> </head>
2.3 随后在要使用 StreamSaver.js 的 ts 文件中声明
file-handle.ts
declare const streamSaver: any; export class FileHandle { static createWrite(fileName: string) { if (!fileName) throw new Error('文件名不能为空'); // 如果没有自己已授信的 https 服务器, 下面 streamSaver.mitm = 'https://xxx_ip:xxx_port/other/mitm.html?version=2.0.0'; 可删除. // 会走默认服务器: https://jimmywarting.github.io/StreamSaver.js/mitm.html?version=2.0.0 streamSaver.mitm = 'https://xxx_ip:xxx_port/other/mitm.html?version=2.0.0'; // 创建一个可写流 return streamSaver.createWriteStream(fileName).getWriter(); } }
补充: 如果使用 npm 安装使用 streamsaver, 在配置另外授信的 https 服务器的时候, ts 会报错, 所以最好还是将 StreamSaver.js 文件直接放到项目中使用.
import * as streamSaver from 'streamsaver';
streamSaver.mitm = 'https://xxx_ip:xxx_port/other/mitm.html?version=2.0.0';
npm i streamsaver
npm i @types/streamsaver
3. 使用 streamSaver 完成下载
download = () => { const writer = FileHandle.createWrite(); // 伪代码 for(let i = 0; i++; i <= 10) { this.http.post('/download', ...).subscribe(next => { writer.write(next); }); } write.end(); }
4. 如果下载文件不想借助 StreamSaver 默认的 https 服务器, 需要在 nginx 服务器进行如下配置
注意:
nginx 配置的 "other" 路由应当和代码中的 streamSaver.mitm = 'https://xxx_ip:xxx_port/other/mitm.html?version=2.0.0'; 对应起来
# https server { listen 9999ssl; listen [::]:9999 ssl; server_name 0.0.0.0; ssl_certificate /etc/nginx/my-ssl/sss.crt; # crt ssl_certificate_key /etc/nginx/my-ssl/sss.key; # key ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_protocols TLSv1.3; ssl_ciphers 'HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES'; ssl_prefer_server_ciphers on; location / { root /fornt/my-app; index index.html index.htm; try_files $uri $uri/ /index.html; } location ^~/api { proxy_pass https://127.0.0.1:8888; } location ^~/other/mitm.html { alias /streamsaver/mitm.html; } location ^~/other/sw.js { alias /streamsaver/sw.js; } location ^~/other/ping { alias /streamsaver/sw.js; } }
最后重启 nginx , 就将授信 https 服务器改为了自己的服务器.
如果使用的是自签名证书, 又没有在用户电脑安装证书, 需要在浏览器添加如下配置:
--ignore-certificate-errors