Skip to content

Instantly share code, notes, and snippets.

@sweet-zone
Created February 15, 2017 05:01
Show Gist options
  • Select an option

  • Save sweet-zone/aa88979b282e66530aefd024edd2eec5 to your computer and use it in GitHub Desktop.

Select an option

Save sweet-zone/aa88979b282e66530aefd024edd2eec5 to your computer and use it in GitHub Desktop.
Download file using nodejs
/**
* nodejs下载文件
*/
var fs = require('fs');
var url = require('url');
var http;
/**
* @param opts
* opts.url 下载链接
* opts.savePath 下载地址
* opts.callback 回调方法
*
* 回调方法的参数
* state: 1成功 2正在下载 3失败
* finished: 已下载
* total 文件总大小
*/
module.exports = function(opts) {
var http, protocol;
protocol = url.parse(opts.url).protocol;
if(protocol === 'https:') {
http = require('https');
} else {
http = require('http');
}
var file = fs.createWriteStream(opts.savePath);
// 下载超时失败后 会先进入错误处理timeoutWrapper
// 然后触发 end事件
var isError = false;
// abort 会触发 end
var isAbort = false;
var timeoutWrapper = function(req) {
return function() {
console.log('timeout! abort');
isError = true;
req.abort();
opts.callback.call(null, {
state: 3
});
}
}
var requestSave = http.get(opts.url, function(res) {
var len = 0;
if(res.headers['content-length']) {
len = parseInt(res.headers['content-length'], 10);
} else {
len = parseInt(res.headers['entries-size'], 10);
}
var downloaded = 0;
res.on('data', function(chunk) {
file.write(chunk);
downloaded += chunk.length;
opts.callback.call(null, {
state: 1,
finished: downloaded,
total: len
});
// reset timout
clearTimeout(timeoutId);
timeoutId = setTimeout(fn, timeout);
});
res.on('end', function() {
clearTimeout(timeoutId);
if(!isError && !isAbort) {
file.end();
opts.callback.call(null, {
state: 2,
finished: downloaded,
total: len
});
} else {
fs.unlink(opts.savePath);
}
});
res.on('error', function(err) {
clearTimeout(timeoutId);
opts.callback.call(null, {
state: 3,
finished: downloaded,
total: len
});
});
var fn = timeoutWrapper(requestSave);
var timeoutId = setTimeout(fn, timeout);
});
requestSave.on('error', function(err) {
opts.callback.call(null, {
state: 3
});
});
requestSave.on('close', function(err) {
isAbort = true;
});
return requestSave;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment