Node.js从URL下载图像

3

我的问题是从url下载未知扩展名的图片(可能是jpg,png,jpeg或bmp)。因此我想检查图片的Content-Length,如果它大于0,则将其下载到文件中;否则尝试使用另一种扩展名下载图片,依此类推。

var fs = require('fs');
var request = require('request');
var xml2js = require('xml2js');
var Q =  require('q');

var baseUrl = 'http://test.com/uploads/catalog_item_image_main/';

Q.nfcall(fs.readFile, "./test.xml", "utf8")
    .then(parseSrting)
    .then(parseProductsAsync)
    .then(processProductsAsync)
;


function parseSrting(data){
    return Q.nfcall(xml2js.parseString,data);
}

function parseProductsAsync(xmljsonresult){
    return xmljsonresult.product_list.product;
}


function processProductsAsync(products){
    products.map(function(product){

        var filename = product.sku + ""; // - where is image name
        filename = filename.replace(/\//g, '_');
        console.log('Processing file ' + filename);

        var imageUrl = baseUrl + filename + '_big.';  // + image extension

        //There I want to check Content-Length of the image and if it bigger then 0, download it to file,
        //else try download image with another extension and etc.

    });
}

我正在使用Node.js的Q promises模块来避免回调地狱,但有人可以帮助我检查图片大小并将其保存到文件中吗?


直接调用 request 函数可以吗?请使用普通的回调函数,而不是 Promise,告诉我们您需要什么,这样我们就可以帮助您避免回调地狱。 - Bergi
2个回答

4

您可以查看响应的状态码。如果是200,则表示图片已经成功获取。

您可以使用文件扩展名数组和递归方法按顺序尝试每个文件扩展名。使用request模块,您可以像这样做:

function processProductsAsync(products){
    products.map(function(product){

        var filename = product.sku + ""; // - where is image name
        filename = filename.replace(/\//g, '_');
        console.log('Processing file ' + filename);

        var imageUrl = baseUrl + filename + '_big.';  // + image extension

        fetchImage(imageUrl, filename, 0);
});

function fetchImage(url, localPath, index) {
    var extensions = ['jpg', 'png', 'jpeg', 'bmp'];

    if (index === extensions.length) {
        console.log('Fetching ' + url + ' failed.');
        return;
    }

    var fullUrl = url + extensions[index];

    request.get(fullUrl, function(response) {
        if (response.statusCode === 200) {
            fs.write(localPath, response.body, function() {
                console.log('Successfully downloaded file ' + url);
            });
        }

        else {
            fetchImage(url, localPath, index + 1);
        }
    });
}

谢谢,但我遇到了另一个错误:return binding.writeString(fd, buffer, offset, length, req); ^ 类型错误:第一个参数必须是文件描述符 当运行您的代码时。 - MeetJoeBlack
1
@MeetJoeBlack 尝试使用 fs.writeFile(localPath, response.body, 'binary', function (err) {}); - martriay

0

现在请求模块已被弃用,因此它将无法提供更多帮助

尝试使用以下方式的 url 模块

我正在从查询 URL 的详细信息中下载或发送图像响应

const fs = require('fs');
const url = require('url')

download_image: async (req, res) => {


    let query = url.parse(req.url, true).query;
    let pic = query.image;
    let id = query.id

    let directory_name = "tmp/daily_gasoline_report/" + id + "/" + pic

    let filename = fs.existsSync(directory_name);

    if (filename) {

        //read the image using fs and send the image content back in the response
        fs.readFile(directory_name, function (err, content) {
            if (err) {
                res.writeHead(400, { 'Content-type': 'text/html' })
                console.log(err);
                res.end("No such image");
            } else {
                //specify the content type in the response will be an image
                res.writeHead(200);
                res.end(content);
            }
        });
    } else {
        logger.warn(error.NOT_FOUND)
        return res.status(401).send(error.NOT_FOUND)
    }
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接