我正在尝试找到一种使用 node.js 下载大图像(~2MB 及以上)的方法。我到处搜索,尝试了各种解决方案,尽管下载了图像,但有些图像始终损坏。
例如,使用以下代码下载此示例图像是可行的,但图像只下载了一半。
var http = require('http')
var fs = require('fs')
var options = {
host:'images.clipartpanda.com',
port:80,
path:'http://images.clipartpanda.com/writing-clip-art-xTgn7KXTA.jpeg'
};
var downloadImage = function (options, fileName) {
http.get(options, function (res) {
var imageData = '';
res.setEncoding('binary');
res.on('data', function (chunk) {
imageData += chunk;
});
res.on('end', function () {
fs.writeFile(fileName, imageData, 'binary', function(err){
if(err) throw err;
console.log('File: ' + fileName + " written!");
})
});
});
};
downloadImage(options,'writing-clip-art-xTgn7KXTA.jpeg');
我也尝试过使用 npm image-downloader,但得到了相同的结果
var image_downloader = require('image-downloader');
var options = {
url: 'http://images.clipartpanda.com/writing-clip-art-xTgn7KXTA.jpeg',
dest: '/home',
done: function (err, filename, image) {
if (err) {
console.log(err);
} else {
console.log('File saved to', filename);
}
},
};
image_downloader(options);
我使用的是 Ubuntu v16.04 虚拟机和 Node.js v4.2.6。
-更新-
尝试根据下面的答案和评论使用以下代码(现在使用createWriteStream),但文件在下载时仍然被损坏。
var http = require('http')
var fs = require('fs')
var options = {
host:'images.clipartpanda.com',
port:80,
path:'http://images.clipartpanda.com/writing-clip-art-xTgn7KXTA.jpeg'
};
var fileName = 'writing-clip-art-xTgn7KXTA.jpeg';
http.get(options, function (res) {
var stream = fs.createWriteStream(fileName);
res.pipe(stream);
});
我时不时也会收到这样的错误:
Command: node "/home/test.js"
events.js:141
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at exports._errnoException (util.js:870:11)
at TCP.onread (net.js:544:26)
Program exited with code 1
--更新2--
经过无数个小时的搜索来解决这个问题,我想我已经找到了答案。我必须将 {forever: true} 添加到 image-download.js 文件第 21 行的请求中。
request({url: options.url, encoding: null, forever:true}, function (err, response, body) {
似乎套接字连接一直处于死亡状态,需要使用 keepAlive:true 。
最佳答案
您正在获取二进制数据,但要将其附加到字符串中。
你应该做的是处理缓冲区。以下是附加缓冲区的方法:
var newBuffer = Buffer.concat([buffer1, buffer2]);
因此,不要将数据附加到字符串中,而是将每个缓冲区添加到数组中,并使用 Buffer.concat 在末尾连接所有缓冲区。看:
Buffer.concat()
.
或者甚至更好 - 您可以使用流(感谢 Steven Schobert 在评论中指出)。你可以做这样的事情加上一些错误检查和日志记录:
http.get(options, function (res) {
var stream = fs.createWriteStream(fileName);
res.pipe(stream);
});
或者使用更高级别的 API,例如 request
.
当然,您不能排除服务器可能会因为您超出某些速率限制或其他使用条款而对您的请求做出不完整或无效的响应。
关于javascript - Node.js 下载的图像已损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40876473/