断点续传主要利用请求头req.headers['range](Range: bytes=start-end)和响应头res.headers['content-range'](Content-Range:bytes start-end/size)
// 客户端
let http = require('http');
let path = require('path');
// http.request 请求体 http.get 只能发get
let fs = require('fs');
let start = 0;
let limit = 5; // 0-4 5-9
const DOWN_LOAD_URL = path.resolve(__dirname, 'load.txt')
let ws = fs.createWriteStream(DOWN_LOAD_URL);
let pause = false;
process.stdin.on('data',function (data) {
if(data.includes('p')){
pause = true;
}else{
pause = false;
downLoad(); // 重新下载
}
});
function downLoad() {
let options = {
hostname: "localhost",
port: 3000,
method: 'get',
headers: {
Range: `bytes=${start}-${limit + start - 1}`
}
}
http.get(options, function (res) {
let total = res.headers['content-range'].split('/')[1];
// 把请求到的结果生成到当前目录下
//res.pipe(ws, { end: false });
res.on('data',function (chunk) {
ws.write(chunk)
})
res.on('end',function () {
// 累加计算
start += limit;
if (start < total && pause == false) {
setTimeout(() => {
downLoad()
}, 1000);
}
else {
// ws.end();
}
})
})
}
downLoad();
复制代码
//服务端
// 分段请求 range 有范围的请求
// 分段下载
// 前端和服务器说 我要哪一段 100
// 服务器返回对应的内容 给你5个 总大小是100个
// Range:bytes=0-5
// Content-Range: bytes 0-5/7877
let http = require('http');
let path = require('path');
let url = require('url');
let fs = require('fs');
let realPath = path.join(__dirname, 'download.txt');
let statObj = fs.statSync(realPath); // statObj.size 表示文件的总大小
http.createServer((req, res) => {
// let urlObj = url.parse(req.url,true)
let range = req.headers['range'];
console.log(req.method)
if (range) { // 没有分段头 那就表示这个文件整个被返回
let [, start, end] = range.match(/(\d*)-(\d*)/);
console.log(start,end);
start = start ? Number(start) : 0;
end = end ? Number(end) : statObj.size;
res.statusCode = 206;
res.setHeader('Content-Range', `bytes ${start}-${end}/${statObj.size}`);
res.setHeader('Content-Length', end - start + 1);
console.log(end,start);
fs.createReadStream(realPath, { start, end }).pipe(res);
} else {
fs.createReadStream(realPath).pipe(res);
}
}).listen(3000);
// 浏览器 不会自己去记录下载的为止 自己写一个客户端来实现
复制代码