NoteZ_技术博客 NoteZ_技术博客
🏠 首页
  • 📚 Web技术
  • 📋 Npm笔记
  • 📑 Markdown
  • 📄 Git笔记
  • 📝 Nginx文档
  • 📓 Linux文档
  • 📖 技术文档
  • 📜 其他文档
  • 🧊 NodeJs
  • 🎡 Express
  • 🔥 Rust
  • 🎉 Koa2
  • 🍃 MongoDB
  • 🐬 MySql
  • 🥦 Oracle
  • 🍁 Python
  • 🍄 JavaScript
  • 🌰 CSS
  • 🧄 HTML
  • 🥑 Canvas
  • 🌽 Nuxt
  • 🍆 React
  • 🥜 Vue
  • 🧅 TypeScript
  • 🌶️ AI
  • 📘 分类
  • 📗 标签
  • 📙 归档
⚜️ 在线编辑 (opens new window)
  • 📁 站点收藏
  • 📦 前端组件库
  • 📊 数据可视化
  • 🌈 开源插件
  • 🎗️ 关于我
  • 🔗 友情链接
GitHub (opens new window)

NoteZ_技术博客

前端界的小学生
🏠 首页
  • 📚 Web技术
  • 📋 Npm笔记
  • 📑 Markdown
  • 📄 Git笔记
  • 📝 Nginx文档
  • 📓 Linux文档
  • 📖 技术文档
  • 📜 其他文档
  • 🧊 NodeJs
  • 🎡 Express
  • 🔥 Rust
  • 🎉 Koa2
  • 🍃 MongoDB
  • 🐬 MySql
  • 🥦 Oracle
  • 🍁 Python
  • 🍄 JavaScript
  • 🌰 CSS
  • 🧄 HTML
  • 🥑 Canvas
  • 🌽 Nuxt
  • 🍆 React
  • 🥜 Vue
  • 🧅 TypeScript
  • 🌶️ AI
  • 📘 分类
  • 📗 标签
  • 📙 归档
⚜️ 在线编辑 (opens new window)
  • 📁 站点收藏
  • 📦 前端组件库
  • 📊 数据可视化
  • 🌈 开源插件
  • 🎗️ 关于我
  • 🔗 友情链接
GitHub (opens new window)
  • Express

  • Koa2

  • MongoDB

  • MySql

  • NodeJs

    • 2021 年值得使用的 Node.js 框架
    • CentOS 7上安装 Node.js 的 4 种方法
    • Linux 下安装 NodeJs 以及版本的升级和降级
    • node 中 path 模块 normalize 函数格式化路径
    • Node 中 使用 fs.stat() 读取文件状态
    • Node 中使用 compressing 压缩文件夹为 zip 文件
    • Node 中的实现 EventEmitter (event)方法
    • Node 代理 Demo 示例
    • node 判断文件或文件夹是否存在
    • node 复制文件的五种方式
    • Node 常用模块之 fs-extra
    • node 操作 mongodb 数据库备份与还原-示例代码
    • node 获取请求 ip
    • Node 读取和写入 json 文件
    • Node 递归或 mkdirp 创建多层目录
    • Node 遍历目录输出树形文件目录结构
    • Node(publish-sftp)命令上传本地文件到服务器
    • Node.js 中使用 compressing 实现zip文件的解压,解决文件名中文乱码
    • node.js 读取文件目录下的所有读取文件目录
    • Node.js把前台传来的 base64 码转成图片
    • nodeJs + vueJs 实现大文件分片上传
    • NodeJs 使用 jszip 或者 zip-dir 压缩文件夹(zip)
    • NodeJs 利用 jszip 压缩文件、文件夹,以及解压压缩文件中的文件
    • NodeJs 实现简单 WebSocket 即时通讯
    • NodeJs 框架 Express 的两种使用方式
    • NodeJs与Nginx获取客户端真实IP方法
    • NodeJs之大文件断点下载
    • NodeJS使用node-fetch下载文件并显示下载进度
      • 最简单的下载文件
      • 下载较大的文件
      • 断点续传
    • NodeJs将图片进行压缩生成缩略图
    • nodejs递归读取所有文件
    • Node中复制文件的四种方法总结
    • node中的读取流createReadStream、写入流createWriteStream和管道流pipe
    • Node开发笔记
    • Node递归创建多层目录并写入文件
    • Node递归创建文件夹
    • PM2配置文件的使用、管理多个Node.js项目
    • 使用 koa-generator 快速搭建 Koa2 项目
    • 使用 pm2 部署 nodejs 项目
    • 使用 supervisor 自动重启 NodeJs 提高开发效率
    • 使用node反向代理解决跨域问题
    • 使用node实现保存(上传)图片的功能
    • 使用Node搭建超高压缩比的图片(webp)压缩服务
    • 前端部署从静态到node再到负载均衡
    • 在 NodeJs 中使用 compressing 压缩和解压缩文件或文件夹
    • 在 nodejs 执行 shell 指令
    • 基于 Node 生成 vue 模板文件
    • 如何使用 Nodejs 备份 MongoDB 数据
    • 如何使用NodeJs实现base64和png文件相互转换
    • 如何在 Linux 服务器上使用 Nodejs 连接远程 Oracle 数据库
    • 混淆、编译 Node.js 源代码的几种方法
    • Node.js包之archiver压缩打包文件或目录为zip格式
    • node.js获取目录内所有文件大小总和
    • NodeJs 中使用 resize-img 制作缩略图
    • nodeJS中的http模块基本介绍
    • nodejs图片处理工具gm用法
    • node使用ffmpeg将swf转mp4 截取mp4视频第一帧为jpg图片
    • 如何在Node.js中执行shell命令
    • NodeJs 中复制(拷贝)文件或文件夹的多种方式
    • 在 NodeJs 中使用 archiver 压缩超大文件夹
    • Node.js 中使用 ssh2-sftp-client 上传文件并实时获取速率大小和进度
    • Node.js 中使用 ssh2-sftp-client 上传文件到服务器示例
    • node 使用 ssh2-sftp-client 实现 FTP 的文件上传和下载功能
    • ssh2-sftp-client 上传文件夹时获取上传速度和文件夹大小
    • 基于 node 使用 UDP 上传文件示例
    • 利用Node.js监控文件变化并使用sftp上传到服务器
    • 利用 Node 监控文件夹或文件夹变化可用的 npm 包汇总
    • NodeJS获取当前目录、运行文件所在目录、运行文件的上级目录
    • Node与GLIBC_2.27不兼容解决方案
  • Oracle

  • Rust

  • Python

  • 后端开发
  • NodeJs
NoteZ
2020-01-11
目录

NodeJS使用node-fetch下载文件并显示下载进度

# 最简单的下载文件

适用于小文件下载

const fetch = require("node-fetch");
const fs = require("fs");
fetch("文件url",   {
        method: 'GET',
        headers: { 'Content-Type': 'application/octet-stream' },
}).then(res => res.buffer()).then(_=>{
  fs.writeFile("文件保存路径", _, "binary", function (err) {
                if (err) console.error(err);
                else console.log("下载成功");
    });
})
1
2
3
4
5
6
7
8
9
10
11

# 下载较大的文件

const fetch = require("node-fetch");
const fs = require("fs");
const path = require("path");
const progressStream = require('progress-stream');

//下载 的文件 地址
let fileURL = "https://nodejs.org/dist/v12.18.3/node-v12.18.3-x64.msi";
//下载保存的文件路径
let fileSavePath = path.join(__dirname, path.basename(fileURL));
//缓存文件路径
let tmpFileSavePath = fileSavePath + ".tmp";
//创建写入流
const fileStream = fs.createWriteStream(tmpFileSavePath).on('error', function (e) {
    console.error('error==>', e)
}).on('ready', function () {
    console.log("开始下载:", fileURL);
}).on('finish', function () {
    //下载完成后重命名文件
    fs.renameSync(tmpFileSavePath, fileSavePath);
    console.log('文件下载完成:', fileSavePath);
});
//请求文件
fetch(fileURL, {
    method: 'GET',
    headers: { 'Content-Type': 'application/octet-stream' },
    // timeout: 100,    
}).then(res => {
    //获取请求头中的文件大小数据
    let fsize = res.headers.get("content-length");
    //创建进度
    let str = progressStream({
        length: fsize,
        time: 100 /* ms */
    });
    // 下载进度 
    str.on('progress', function (progressData) {
        //不换行输出
        let percentage = Math.round(progressData.percentage) + '%';
        console.log(percentage);
        // process.stdout.write('\033[2J'+);
        // console.log(progress);
        /*
        {
            percentage: 9.05,
            transferred: 949624,
            length: 10485760,
            remaining: 9536136,
            eta: 42,
            runtime: 3,
            delta: 295396,
            speed: 949624
        }
        */
    });
    res.body.pipe(str).pipe(fileStream);
}).catch(e => {
    //自定义异常处理
    console.log(e);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

# 断点续传

这里我根据原理将下载代码进行修改

const fetch = require("node-fetch");
const fs = require("fs");
const path = require("path");
const progressStream = require('progress-stream');

//下载 的文件 地址
let fileURL = "https://npm.taobao.org/mirrors/node/v14.8.0/node-v14.8.0-x64.msi";
//下载保存的文件路径
let fileSavePath = path.join(__dirname, path.basename(fileURL));
//缓存文件路径
let tmpFileSavePath = fileSavePath + ".tmp";
//下载进度信息保存文件
let cfgFileSavePath = fileSavePath + ".cfg.json";

let downCfg = {
    rh: {},//请求头
    percentage: 0,//进度
    transferred: 0,//已完成
    length: 0,//文件大小
    remaining: 0,//剩余
    first: true//首次下载
};
let tmpFileStat = { size: 0 };
//判断文件缓存 与 进度信息文件是否存在 
if (fs.existsSync(tmpFileSavePath) && fs.existsSync(cfgFileSavePath)) {
    tmpFileStat = fs.statSync(tmpFileSavePath);
    downCfg = JSON.parse(fs.readFileSync(cfgFileSavePath, 'utf-8').trim());
    downCfg.first = false;
    //设置文件
    downCfg.transferred = tmpFileStat.size;
}

//创建写入流
let writeStream = null;

//请求头
let fetchHeaders = {
    'Content-Type': 'application/octet-stream',
    "Cache-Control": "no-cache",
    Connection: "keep-alive",
    Pragma: "no-cache",
};
//追加请求范围
if (downCfg.length != 0) {
    fetchHeaders.Range = "bytes=" + downCfg.transferred + "-" + downCfg.length;//71777113
}
if (downCfg.rh["last-modified"]) {
    fetchHeaders["last-modified"] = downCfg.rh["last-modified"];
}
//校验文件头
const checkHerder = [
    "last-modified",//文件最后修改时间
    "server",//服务器
    // "content-length",//文件大小
    "content-type",//返回类型
    "etag",//文件标识
];

fetch(fileURL, {
    method: 'GET',
    headers: fetchHeaders,
    // timeout: 100,    
}).then(res => {
    let h = {};
    res.headers.forEach(function (v, i, a) { h[i.toLowerCase()] = v; });
    // console.log(h);
    //文件是否发生变化
    let fileIsChange = false;
    //是否首次下载
    if (downCfg.first) {
        //记录相关信息
        for (let k of checkHerder) downCfg.rh[k] = h[k];
        downCfg.length = h["content-length"];
    } else {
        //比较响应变化
        for (let k of checkHerder) {
            if (downCfg.rh[k] != h[k]) {
                fileIsChange = true;
                break;
            }
        }
        //是否运行范围下载
        downCfg.range = res.headers.get("content-range") ? true : false;
    }
    //创建文件写入流
    writeStream = fs.createWriteStream(tmpFileSavePath, { 'flags': !downCfg.range || fileIsChange ? 'w' : 'a' })
        .on('error', function (e) {
            console.error('error==>', e)
        }).on('ready', function () {
            console.log("开始下载:", fileURL);
        }).on('finish', function () {
            //下载完成后重命名文件
            fs.renameSync(tmpFileSavePath, fileSavePath);
            fs.unlinkSync(cfgFileSavePath);
            console.log('文件下载完成:', fileSavePath);
        });

    //写入信息文件
    fs.writeFileSync(cfgFileSavePath, JSON.stringify(downCfg));
    //获取请求头中的文件大小数据
    let fsize = h["content-length"];
    //创建进度
    let str = progressStream({
        length: fsize,
        time: 200 /* ms */
    });
    //创建进度对象
    str.on('progress', function (progressData) {
        //不换行输出
        let percentage = Math.round(progressData.percentage) + '%';
        console.log(percentage);
        //     console.log(`
        //     进度 ${progressData.percentage}
        //     已完成 ${progressData.transferred}
        //     文件大小 ${progressData.length}
        //     剩余 ${progressData.remaining}
        //         ${progressData.eta}
        //     运行时 ${progressData.runtime}
        //         ${ progressData.delta}
        //    速度 ${ progressData.speed}
        //             `);
        // console.log(progress);
        /*
        {
            percentage: 9.05,
            transferred: 949624,
            length: 10485760,
            remaining: 9536136,
            eta: 42,
            runtime: 3,
            delta: 295396,
            speed: 949624
        }
        */
    });
    res.body.pipe(str).pipe(writeStream);
    res.headers.forEach(function (v, i, a) {
        console.log(i + " : " + v);
    })
}).catch(e => {
    //自定义异常处理
    console.log(e);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#NodeJs
上次更新: 2024/01/30, 00:35:17
NodeJs之大文件断点下载
NodeJs将图片进行压缩生成缩略图

← NodeJs之大文件断点下载 NodeJs将图片进行压缩生成缩略图→

最近更新
01
Gitea数据备份与还原
03-10
02
Linux 中使用 rsync 同步文件目录教程
03-10
03
Linux 使用 rsync 互相传输同步文件的简单步骤
03-08
更多文章>
Theme by Vdoing | Copyright © 2019-2025 NoteZ,All rights reserved | 冀ICP备2021027292号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式