How to download a file with Node.js using HTTPS?
Using standard Node modules only:
const fs = require('fs');
const http = require('http');
const https = require('https');
/**
* Downloads file from remote HTTP[S] host and puts its contents to the
* specified location.
*/
async function download(url, filePath) {
const proto = !url.charAt(4).localeCompare('s') ? https : http;
return new Promise((resolve, reject) => {
const file = fs.createWriteStream(filePath);
let fileInfo = null;
const request = proto.get(url, response => {
if (response.statusCode !== 200) {
fs.unlink(filePath, () => {
reject(new Error(`Failed to get '${url}' (${response.statusCode})`));
});
return;
}
fileInfo = {
mime: response.headers['content-type'],
size: parseInt(response.headers['content-length'], 10),
};
response.pipe(file);
});
// The destination stream is ended by the time it's called
file.on('finish', () => resolve(fileInfo));
request.on('error', err => {
fs.unlink(filePath, () => reject(err));
});
file.on('error', err => {
fs.unlink(filePath, () => reject(err));
});
request.end();
});
}
You should use https
module then. Quoting the docs:
HTTPS is the HTTP protocol over TLS/SSL. In Node this is implemented as a separate module.
The good news is that the request-related methods of that module (https.request()
, https.get()
etc.) support all the options that the ones from http
do.
Keeping it simple:
var fs = require('fs-extra');
var fetch = require('node-fetch');
/**
* Download a file to disk
* @example downloadFile('https://orcascan.com', './barcode-tracking.html')
* @param {string} fileUrl - url of file to download
* @param {string} destPath - destination path
* @returns {Promise} resolves once complete, otherwise rejects
*/
function downloadFile(fileUrl, destPath) {
if (!fileUrl) return Promise.reject(new Error('Invalid fileUrl'));
if (!destPath) return Promise.reject(new Error('Invalid destPath'));
return new Promise(function(resolve, reject) {
fetch(fileUrl).then(function(res) {
var fileStream = fs.createWriteStream(destPath);
res.body.on('error', reject);
fileStream.on('finish', resolve);
res.body.pipe(fileStream);
});
});
}