Cómo descargar un archivo con Node.js (sin usar bibliotecas de terceros)?
Cómo puedo descargar un archivo con Node.js sin usar bibliotecas de terceros?
No necesito nada especial. Solo quiero descargar un archivo de una URL dada, y luego guardarlo en un directorio dado.19 answers
Puede crear una solicitud HTTP GET
y canalizar su response
en una secuencia de archivos de escritura:
var http = require('http');
var fs = require('fs');
var file = fs.createWriteStream("file.jpg");
var request = http.get("http://i3.ytimg.com/vi/J---aiyznGQ/mqdefault.jpg", function(response) {
response.pipe(file);
});
Si quieres apoyar la recopilación de información en la línea de comandos specifying como especificar un archivo o directorio de destino, o URL check echa un vistazo a algo como Commander.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-12 01:04:59
No se olvide de manejar los errores! El siguiente código está basado en la respuesta de Augusto Roman.
var http = require('http');
var fs = require('fs');
var download = function(url, dest, cb) {
var file = fs.createWriteStream(dest);
var request = http.get(url, function(response) {
response.pipe(file);
file.on('finish', function() {
file.close(cb); // close() is async, call cb after close completes.
});
}).on('error', function(err) { // Handle errors
fs.unlink(dest); // Delete the file async. (But we don't check the result)
if (cb) cb(err.message);
});
};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-07 08:24:11
Como dijo Brandon Tilley, pero con el flujo de control apropiado:
var http = require('http');
var fs = require('fs');
var download = function(url, dest, cb) {
var file = fs.createWriteStream(dest);
var request = http.get(url, function(response) {
response.pipe(file);
file.on('finish', function() {
file.close(cb);
});
});
}
Sin esperar el evento finish
, los scripts ingenuos pueden terminar con un archivo incompleto.
Edit: Gracias a @Augusto Roman por señalar que cb
se debe pasar a file.close
, no se debe llamar explícitamente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-12 23:59:20
Hablando de manejar errores, es incluso mejor escuchar errores de solicitud también. Incluso validaría comprobando el código de respuesta. Aquí se considera éxito solo para el código de respuesta 200, pero otros códigos podrían ser buenos.
var fs = require('fs');
var http = require('http');
var download = function(url, dest, cb) {
var file = fs.createWriteStream(dest);
var request = http.get(url, function(response) {
// check if response is success
if (response.statusCode !== 200) {
return cb('Response status was ' + response.statusCode);
}
response.pipe(file);
file.on('finish', function() {
file.close(cb); // close() is async, call cb after close completes.
});
});
// check for request error too
request.on('error', function (err) {
fs.unlink(dest);
return cb(err.message);
});
file.on('error', function(err) { // Handle errors
fs.unlink(dest); // Delete the file async. (But we don't check the result)
return cb(err.message);
});
};
A pesar de la relativa simplicidad de este código, recomendaría usar el módulo de solicitud ya que maneja muchos más protocolos (hello HTTPS!) que no son soportados de forma nativa por http
.
Eso se haría así:
var fs = require('fs');
var request = require('request');
var download = function(url, dest, cb) {
var file = fs.createWriteStream(dest);
var sendReq = request.get(url);
// verify response code
sendReq.on('response', function(response) {
if (response.statusCode !== 200) {
return cb('Response status was ' + response.statusCode);
}
});
// check for request errors
sendReq.on('error', function (err) {
fs.unlink(dest);
return cb(err.message);
});
sendReq.pipe(file);
file.on('finish', function() {
file.close(cb); // close() is async, call cb after close completes.
});
file.on('error', function(err) { // Handle errors
fs.unlink(dest); // Delete the file async. (But we don't check the result)
return cb(err.message);
});
};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-22 01:53:27
La respuesta de Gfxmonk tiene una carrera de datos muy apretada entre la devolución de llamada y la file.close()
completando. file.close()
en realidad recibe una devolución de llamada que se llama cuando se ha completado el cierre. De lo contrario, los usos inmediatos del archivo pueden fallar (¡muy raramente!).
Una solución completa es:
var http = require('http');
var fs = require('fs');
var download = function(url, dest, cb) {
var file = fs.createWriteStream(dest);
var request = http.get(url, function(response) {
response.pipe(file);
file.on('finish', function() {
file.close(cb); // close() is async, call cb after close completes.
});
});
}
Sin esperar el evento finish, los scripts ingenuos pueden terminar con un archivo incompleto. Sin programar la devolución de llamada cb
a través de close, puede obtener una carrera entre el acceso al archivo y el archivo en realidad estar listo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-02 20:32:07
Solución con tiempo de espera, evitar fugas de memoria:
El siguiente código se basa en la respuesta de Brandon Tilley :
var http = require('http'),
fs = require('fs');
var request = http.get("http://example12345.com/yourfile.html", function(response) {
if (response.statusCode === 200) {
var file = fs.createWriteStream("copy.html");
response.pipe(file);
}
// Add timeout.
request.setTimeout(12000, function () {
request.abort();
});
});
No cree un archivo cuando obtenga un error, y prefiere usar el tiempo de espera para cerrar su solicitud después de X segundos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-02 19:11:12
Para aquellos que vinieron en busca de una forma basada en promesas al estilo es6, supongo que sería algo como:
var http = require('http');
var fs = require('fs');
function pDownload(url, dest){
var file = fs.createWriteStream(dest);
return new Promise((resolve, reject) => {
var responseSent = false; // flag to make sure that response is sent only once.
http.get(url, response => {
response.pipe(file);
file.on('finish', () =>{
file.close(() => {
if(responseSent) return;
responseSent = true;
resolve();
});
});
}).on('error', err => {
if(responseSent) return;
responseSent = true;
reject(err);
});
});
}
//example
pDownload(url, fileLocation)
.then( ()=> console.log('downloaded file no issues...'))
.catch( e => console.error('error while downloading', e));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-30 07:49:28
Tal vez nodo.js ha cambiado, pero parece que hay algunos problemas con las otras soluciones (usando el nodo v8.1.2):
- No es necesario llamar a
file.close()
en el eventofinish
. Por defecto elfs.createWriteStream
se establece en AutoClose: https://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options -
file.close()
debe invocarse en caso de error. Tal vez esto no sea necesario cuando se elimina el archivo (unlink()
), pero normalmente lo es: https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options - El archivo temporal no se elimina en
statusCode !== 200
-
fs.unlink()
sin una devolución de llamada está en desuso (advertencia de salidas) - Si el archivo
dest
existe; se anula
A continuación se muestra una solución modificada (utilizando ES6 y promises) que maneja estos problemas.
const http = require("http");
const fs = require("fs");
function download(url, dest) {
return new Promise((resolve, reject) => {
const file = fs.createWriteStream(dest, { flags: "wx" });
const request = http.get(url, response => {
if (response.statusCode === 200) {
response.pipe(file);
} else {
file.close();
fs.unlink(dest, () => {}); // Delete temp file
reject(`Server responded with ${response.statusCode}: ${response.statusMessage}`);
}
});
request.on("error", err => {
file.close();
fs.unlink(dest, () => {}); // Delete temp file
reject(err.message);
});
file.on("finish", () => {
resolve();
});
file.on("error", err => {
file.close();
if (err.code === "EEXIST") {
reject("File already exists");
} else {
fs.unlink(dest, () => {}); // Delete temp file
reject(err.message);
}
});
});
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-10 08:52:43
El código de Vince Yuan es genial, pero parece que algo anda mal.
function download(url, dest, callback) {
var file = fs.createWriteStream(dest);
var request = http.get(url, function (response) {
response.pipe(file);
file.on('finish', function () {
file.close(callback); // close() is async, call callback after close completes.
});
file.on('error', function (err) {
fs.unlink(dest); // Delete the file async. (But we don't check the result)
if (callback)
callback(err.message);
});
});
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-02 07:06:09
Puedes usar https://github.com/douzi8/ajax-request#download
request.download('http://res.m.ctrip.com/html5/Content/images/57.png',
function(err, res, body) {}
);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-04 03:11:44
const download = (url, path) => new Promise((resolve, reject) => {
http.get(url, response => {
const statusCode = response.statusCode;
if (statusCode !== 200) {
return reject('Download error!');
}
const writeStream = fs.createWriteStream(path);
response.pipe(writeStream);
writeStream.on('error', () => reject('Error writing to file!'));
writeStream.on('finish', () => writeStream.close(resolve));
});}).catch(err => console.error(err));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-18 21:14:47
Ruta: img tipo : jpg random uniqid
function resim(url) {
var http = require("http");
var fs = require("fs");
var sayi = Math.floor(Math.random()*10000000000);
var uzanti = ".jpg";
var file = fs.createWriteStream("img/"+sayi+uzanti);
var request = http.get(url, function(response) {
response.pipe(file);
});
return sayi+uzanti;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-23 15:54:10
Si está utilizando express use el método res.download (). de lo contrario, el uso del módulo fs.
app.get('/read-android', function(req, res) {
var file = "/home/sony/Documents/docs/Android.apk";
res.download(file)
});
(o)
function readApp(req,res) {
var file = req.fileName,
filePath = "/home/sony/Documents/docs/";
fs.exists(filePath, function(exists){
if (exists) {
res.writeHead(200, {
"Content-Type": "application/octet-stream",
"Content-Disposition" : "attachment; filename=" + file});
fs.createReadStream(filePath + file).pipe(res);
} else {
res.writeHead(400, {"Content-Type": "text/plain"});
res.end("ERROR File does NOT Exists.ipa");
}
});
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-18 09:19:50
Descarga usando promise, que resuelven un flujo legible. pon lógica extra para manejar la redirección.
var http = require('http');
var promise = require('bluebird');
var url = require('url');
var fs = require('fs');
var assert = require('assert');
function download(option) {
assert(option);
if (typeof option == 'string') {
option = url.parse(option);
}
return new promise(function(resolve, reject) {
var req = http.request(option, function(res) {
if (res.statusCode == 200) {
resolve(res);
} else {
if (res.statusCode === 301 && res.headers.location) {
resolve(download(res.headers.location));
} else {
reject(res.statusCode);
}
}
})
.on('error', function(e) {
reject(e);
})
.end();
});
}
download('http://localhost:8080/redirect')
.then(function(stream) {
try {
var writeStream = fs.createWriteStream('holyhigh.jpg');
stream.pipe(writeStream);
} catch(e) {
console.error(e);
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-12 02:33:36
function download(url, dest, cb) {
var request = http.get(url, function (response) {
const settings = {
flags: 'w',
encoding: 'utf8',
fd: null,
mode: 0o666,
autoClose: true
};
// response.pipe(fs.createWriteStream(dest, settings));
var file = fs.createWriteStream(dest, settings);
response.pipe(file);
file.on('finish', function () {
let okMsg = {
text: `File downloaded successfully`
}
cb(okMsg);
file.end();
});
}).on('error', function (err) { // Handle errors
fs.unlink(dest); // Delete the file async. (But we don't check the result)
let errorMsg = {
text: `Error in file downloadin: ${err.message}`
}
if (cb) cb(errorMsg);
});
};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-09 05:25:46
Puede intentar usar res.redirect
a la url de descarga del archivo https, y luego se descargará el archivo.
Como: res.redirect('https//static.file.com/file.txt');
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-07 13:03:01
Sin biblioteca podría tener errores solo para señalar. Aquí están algunos:
- No puede manejar la redirección http, como esta url https://calibre-ebook.com/dist/portable que es binario.
- el módulo http no puede url https, obtendrá
Protocol "https:" not supported.
Aquí mi sugerencia:
- Herramienta del sistema de llamadas como
wget
ocurl
- use alguna herramienta como node-wget-promise que también es muy simple de usar.
var wget = require('node-wget-promise'); wget('http://nodejs.org/images/logo.svg');
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-25 03:25:42
var requestModule=require("request");
requestModule(filePath).pipe(fs.createWriteStream('abc.zip'));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-01 09:30:21
Podemos usar el módulo de nodo de descarga y es muy simple, consulte a continuación https://www.npmjs.com/package/download
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-18 05:20:42