Kevin Amorim Kevin Amorim - 22 days ago 15
Node.js Question

Node.JS Download file to server following redirects

I'm trying to download Facebook profile pictures using Node.JS, but I'm having problems because Facebook does a redirect.

URL: https://graph.facebook.com/userId/picture?type=large

My download function:

var fs = require('fs');
var https = require('follow-redirects').https;

var download = function(uri, filename) {
var deferred = Q.defer();

var data = "";
https.get(uri, function(response) {
response.on('data', function(chunk) {
console.log(chunk);
data += chunk;
});

response.on('end', function() {
fs.writeFile(filename, data, 'binary', function(err) {
if(err) {
console.log(err.message);
} else {
deferred.resolve();
}
})
});

}).on('error', function(err) {
fs.unlink(filename);
deferred.reject(err);
});

return deferred.promise;
};


I only get one chunk, so the resulting file is corrupted.

How can I solve this?

Answer

Try this:

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

function download(uri, filename) {
    var protocol = url.parse(uri).protocol.slice(0, -1);
    var deferred = Q.defer();
    var onError = function (e) {
        fs.unlink(filename);
        deferred.reject(e);
    }
    require(protocol).get(uri, function(response) {
        if (response.statusCode >= 200 && response.statusCode < 300) {
            var fileStream = fs.createWriteStream(filename);
            fileStream.on('error', onError);
            fileStream.on('close', deferred.resolve);
            response.pipe(fileStream);
        } else if (response.headers.location) {
            deferred.resolve(download(response.headers.location, filename));
        } else {
            deferred.reject(new Error(response.statusCode + ' ' + response.statusMessage));
        }
    }).on('error', onError);
    return deferred.promise;
};
Comments