用node.js下载图像

我正在尝试编写一个脚本来使用node.js下载图像。 这是我迄今为止:

var maxLength = 10 // 10mb var download = function(uri, callback) { http.request(uri) .on('response', function(res) { if (res.headers['content-length'] > maxLength*1024*1024) { callback(new Error('Image too large.')) } else if (!~[200, 304].indexOf(res.statusCode)) { callback(new Error('Received an invalid status code.')) } else if (!res.headers['content-type'].match(/image/)) { callback(new Error('Not an image.')) } else { var body = '' res.setEncoding('binary') res .on('error', function(err) { callback(err) }) .on('data', function(chunk) { body += chunk }) .on('end', function() { // What about Windows?! var path = '/tmp/' + Math.random().toString().split('.').pop() fs.writeFile(path, body, 'binary', function(err) { callback(err, path) }) }) } }) .on('error', function(err) { callback(err) }) .end(); } 

然而,我想要使这个更强大:

  1. 有没有图书馆这样做,做得更好?
  2. 有没有机会回应标题(关于长度,关于内容types)?
  3. 还有其他我应该关心的身份代码吗? 我应该打扰redirect吗?
  4. 我想我读的地方binary编码将被弃用。 那我该怎么办?
  5. 我怎样才能得到这个在Windows上工作?
  6. 任何其他方法可以使这个脚本更好?

为什么:对于类似于imgur的function,用户可以给我一个URL,我下载该图像,并以多种尺寸重新放置图像。

我build议使用请求模块 。 下载文件和下面的代码一样简单:

 var fs = require('fs'), request = require('request'); var download = function(uri, filename, callback){ request.head(uri, function(err, res, body){ console.log('content-type:', res.headers['content-type']); console.log('content-length:', res.headers['content-length']); request(uri).pipe(fs.createWriteStream(filename)).on('close', callback); }); }; download('https://www.google.comhttp://img.dovov.comsrpr/logo3w.png', 'google.png', function(){ console.log('done'); }); 

前几天我遇到了这个问题,对于一个纯粹的NodeJS答案,我会build议使用Stream将块合并在一起。

 var http = require('http'), Stream = require('stream').Transform, fs = require('fs'); var url = 'http://www.google.comhttp://img.dovov.comsrpr/logo11w.png'; http.request(url, function(response) { var data = new Stream(); response.on('data', function(chunk) { data.push(chunk); }); response.on('end', function() { fs.writeFileSync('image.png', data.read()); }); }).end(); 

最新的Node版本对于二进制string将不能很好地工作,所以在处理二进制数据时将块与string合并不是一个好主意。

*使用'data.read()'时要小心,它会清空下一个'read()'操作的stream。 如果您想多次使用它,请将其存储在某个地方。

基于上述,如果有人需要处理写入/读取stream中的错误,我使用了这个版本。 请注意stream.read()在写入错误的情况下,这是必需的,所以我们可以读取stream完成读取和触发close

 var download = function(uri, filename, callback){ request.head(uri, function(err, res, body){ if (err) callback(err, filename); else { var stream = request(uri); stream.pipe( fs.createWriteStream(filename) .on('error', function(err){ callback(error, filename); stream.read(); }) ) .on('close', function() { callback(null, filename); }); } }); }; 

如果你想进度下载试试这个:

 var fs = require('fs'); var request = require('request'); var progress = require('request-progress'); module.exports = function (uri, path, onProgress, onResponse, onError, onEnd) { progress(request(uri)) .on('progress', onProgress) .on('response', onResponse) .on('error', onError) .on('end', onEnd) .pipe(fs.createWriteStream(path)) }; 

如何使用:

  var download = require('../lib/download'); download("https://www.google.comhttp://img.dovov.combranding/googlelogo/2x/googlelogo_color_150x54dp.png", "~/download/logo.png", function (state) { console.log("progress", state); }, function (response) { console.log("status code", response.statusCode); }, function (error) { console.log("error", error); }, function () { console.log("done"); }); 

注意:您应该使用以下命令安装请求和请求进度模块:

 npm install request request-progress --save