通过请求在Node.js中获取下载进度
我正在创建一个更新程序,使用节点模块通过请求在Node.js中获取下载进度,node.js,download,request,progress,Node.js,Download,Request,Progress,我正在创建一个更新程序,使用节点模块request下载应用程序文件。如何使用chunk.length估计剩余的文件大小?以下是我的部分代码: var file_url = 'http://foo.com/bar.zip'; var out = fs.createWriteStream('baz.zip'); var req = request({ method: 'GET', uri: file_url }); req.pipe(out); req.on('data', f
request
下载应用程序文件。如何使用chunk.length
估计剩余的文件大小?以下是我的部分代码:
var file_url = 'http://foo.com/bar.zip';
var out = fs.createWriteStream('baz.zip');
var req = request({
method: 'GET',
uri: file_url
});
req.pipe(out);
req.on('data', function (chunk) {
console.log(chunk.length);
});
req.on('end', function() {
//Do something
});
这应该可以得到您想要的总数:
req.on( 'response', function ( data ) {
console.log( data.headers[ 'content-length' ] );
} );
我得到的内容长度为9404541
函数下载(url、回调、编码){
function download(url, callback, encoding){
var request = http.get(url, function(response) {
if (encoding){
response.setEncoding(encoding);
}
var len = parseInt(response.headers['content-length'], 10);
var body = "";
var cur = 0;
var obj = document.getElementById('js-progress');
var total = len / 1048576; //1048576 - bytes in 1Megabyte
response.on("data", function(chunk) {
body += chunk;
cur += chunk.length;
obj.innerHTML = "Downloading " + (100.0 * cur / len).toFixed(2) + "% " + (cur / 1048576).toFixed(2) + " mb\r" + ".<br/> Total size: " + total.toFixed(2) + " mb";
});
response.on("end", function() {
callback(body);
obj.innerHTML = "Downloading complete";
});
request.on("error", function(e){
console.log("Error: " + e.message);
});
});
};
var request=http.get(url,函数(响应){
if(编码){
响应。设置编码(编码);
}
var len=parseInt(response.headers['content-length'],10);
var body=“”;
var-cur=0;
var obj=document.getElementById('js-progress');
var total=len/1048576;//1048576-1Megabyte中的字节
关于(“数据”,函数(块){
body+=块;
cur+=chunk.length;
obj.innerHTML=“下载”+(100.0*cur/len).toFixed(2)+“%”+(cur/1048576).toFixed(2)+“mb\r”+”
总大小:“+Total.toFixed(2)+“mb”;
});
on(“end”,function()){
回调(体);
obj.innerHTML=“下载完成”;
});
请求打开(“错误”,函数(e){
console.log(“错误:+e.message”);
});
});
};
我编写了一个模块,它只做您想要的事情:
使用cool模块,您可以在es2015中执行以下操作:
import { createWriteStream } from 'fs'
import request from 'request'
import progress from 'request-progress'
progress(request('http://foo.com/bar.zip'))
.on('progress', state => {
console.log(state)
/*
{
percentage: 0.5, // Overall percentage (between 0 to 1)
speed: 554732, // The download speed in bytes/sec
size: {
total: 90044871, // The total payload size in bytes
transferred: 27610959 // The transferred payload size in bytes
},
time: {
elapsed: 36.235, // The total elapsed seconds since the start (3 decimals)
remaining: 81.403 // The remaining seconds to finish (3 decimals)
}
}
*/
})
.on('error', err => console.log(err))
.on('end', () => {})
.pipe(createWriteStream('bar.zip'))
如果有人想知道进度,而不使用其他库,而只是请求,那么您可以使用以下方法:
function downloadFile(file_url , targetPath){
// Save variable to know progress
var received_bytes = 0;
var total_bytes = 0;
var req = request({
method: 'GET',
uri: file_url
});
var out = fs.createWriteStream(targetPath);
req.pipe(out);
req.on('response', function ( data ) {
// Change the total bytes value to get progress later.
total_bytes = parseInt(data.headers['content-length' ]);
});
req.on('data', function(chunk) {
// Update the received bytes
received_bytes += chunk.length;
showProgress(received_bytes, total_bytes);
});
req.on('end', function() {
alert("File succesfully downloaded");
});
}
function showProgress(received,total){
var percentage = (received * 100) / total;
console.log(percentage + "% | " + received + " bytes out of " + total + " bytes.");
// 50% | 50000 bytes received out of 100000 bytes.
}
downloadFile("https://static.pexels.com/photos/36487/above-adventure-aerial-air.jpg","c:/path/to/local-image.jpg");
received_bytes
变量保存每个发送的区块长度的总和,并根据total_bytes
,检索进度。如果您正在使用“请求”模块,并且希望在不使用任何额外模块的情况下显示下载百分比,则可以使用以下代码:
function getInstallerFile (installerfileURL,installerfilename) {
// Variable to save downloading progress
var received_bytes = 0;
var total_bytes = 0;
var outStream = fs.createWriteStream(installerfilename);
request
.get(installerfileURL)
.on('error', function(err) {
console.log(err);
})
.on('response', function(data) {
total_bytes = parseInt(data.headers['content-length']);
})
.on('data', function(chunk) {
received_bytes += chunk.length;
showDownloadingProgress(received_bytes, total_bytes);
})
.pipe(outStream);
};
function showDownloadingProgress(received, total) {
var platform = "win32"; // Form windows system use win32 for else leave it empty
var percentage = ((received * 100) / total).toFixed(2);
process.stdout.write((platform == 'win32') ? "\033[0G": "\r");
process.stdout.write(percentage + "% | " + received + " bytes downloaded out of " + total + " bytes.");
}
用法:
getInstallerFile("http://example.com/bar.zip","bar.zip");
谢谢那个长度是字节吗?是的。它是i个字节。我在.zip:node-webkit.app/中,当我提取数据->无法再运行.app:/my code::fs.writeFileSync(frameZipFilePath,data,“binary”);var zip=新的AdmZip(frameZipFilePath);extractAllTo(path.resolve(“,“tmp”),true);
1048576
来自哪里?这是一个宇宙常数吗?但是对于分块响应,即包含多个分块的大流跳过内容长度标题。那么我们该怎么办?1048576是1024平方字节一兆字节的字节数是的,最初我使用了你的模块,但我希望能够通过WebSocket在GUI中向用户显示进度条。你可以这样做。调用渲染函数时,将状态栏发送给客户端。它是一个字符串,你可以用它做任何事情。是的,但在某种程度上,你自己写东西比解析另一个模块的字符串更容易。:)谢谢你的提示。我四天前更新了这个模块。现在它不返回字符串,而是返回原始数据,因此您可以在服务器或客户端中呈现状态栏。我已经编辑了答案。这些看起来像是很棒的更新!我喜欢它的文档化程度。我肯定会考虑将来使用它。完美的工作只需要声明平台变量和安装程序文件到文件名保存
getInstallerFile("http://example.com/bar.zip","bar.zip");