通过节点请求模块下载的图像已损坏

Image download via node request module is corrupt

我正在尝试通过 npm request module, and save with fs.writeFile, however the file is corrupt when saved on disk, verified with the imagemagick identify 命令下载图像。

const fs = require('fs');
const path = require('path');
const request = require('request');

const brandLogoUrl  = 'https://example.net/logo.png';
const filename      = path.basename(brandLogoUrl);
const brandLogoPath = `./${filename}`;

request(brandLogoUrl, (error, rsp, body) =>  {
        fs.writeFile(brandLogoPath, body, 'binary', (err) => {
            console.log('brand logo saved');
        });
    });
});

当我用identify检查保存的文件时,结果:

identify: improper image header `logo.png' @ error/png.c/ReadPNGImage/3940.

但是,如果我通过 wget 下载相同的 URL 并用 identify 检查它,结果是

logo.png PNG 283x109 283x109+0+0 8-bit sRGB 19KB 0.000u 0:00.000

JS 看起来很简单,但我似乎忽略了一些东西。你能发现吗?

编辑

我尝试了 https 模块(基于 this post),它有效

var fs = require('fs');
var https = require('https');
//Node.js Function to save image from External URL.
var url = 'https://example.net/logo.png';
var file = fs.createWriteStream('./logo.png');
https.get(url, function(response) {
    response.pipe(file);
});

您缺少的是响应的编码。当您使用此库发出请求时,默认情况下它被编码为字符串 (utf-8)。根据 documentation of the request module,您必须传递 encoding: null 才能正确获取二进制数据。

因此您的代码应如下所示:

request({ url: brandLogoUrl, encoding: null }, (error, rsp, body) =>  {
  fs.writeFile(brandLogoPath, body, 'binary', (err) => {
    console.log('brand logo saved');
  });
});

这也是 https 模块运行良好的原因——它只传递原始数据,没有任何编码。