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
  1. 使用 streamSaver 完成下载
复制代码
download = () => {
    const writer = FileHandle.createWrite();
    // 伪代码
    for(let i = 0; i++; i <= 10) {
        this.http.post('/download', ...).subscribe(next => {
            writer.write(next);
        });
    }
    write.end();
}
  1. 如果下载文件不想借助 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;
    }

}   

将 mitm.html 和 sw.js 文件放到 nginx 服务器 /streamsaver 目录下

最后重启 nginx , 就将授信 https 服务器改为了自己的服务器.

如果使用的是自签名证书, 又没有在用户电脑安装证书, 需要在浏览器添加如下配置:

--ignore-certificate-errors

相关推荐
m0_528723811 小时前
HTML中,title和h1标签的区别是什么?
前端·html
Dark_programmer1 小时前
html - - - - - modal弹窗出现时,页面怎么能限制滚动
前端·html
GDAL1 小时前
HTML Canvas clip 深入全面讲解
前端·javascript·canvas
禾苗种树1 小时前
在 Vue 3 中使用 ECharts 制作多 Y 轴折线图时,若希望 **Y 轴颜色自动匹配折线颜色**且无需手动干预,可以通过以下步骤实现:
前端·vue.js·echarts
贵州数擎科技有限公司1 小时前
使用 Three.js 实现流光特效
前端·webgl
JustHappy1 小时前
「我们一起做组件库🌻」做个面包屑🥖,Vue的依赖注入实战💉(VersakitUI开发实录)
前端·javascript·github
拉不动的猪2 小时前
刷刷题16
前端·javascript·面试
支撑前端荣耀2 小时前
基于 Vue 的响应式瀑布流实现全景解析
前端·javascript·面试
祈澈菇凉3 小时前
如何结合使用thread-loader和cache-loader以获得最佳效果?
前端
垣宇3 小时前
Vite 和 Webpack 的区别和选择
前端·webpack·node.js