update tutorial node framework ejemplos actualizar javascript node.js express download fs

javascript - tutorial - node.js download



¿Cómo descargar un archivo con Node.js(sin usar bibliotecas de terceros)? (19)

¿Cómo descargo un archivo con Node.js sin usar bibliotecas de terceros ?

No necesito nada especial. Solo quiero descargar un archivo desde una URL determinada y luego guardarlo en un directorio determinado.


Solución con timeout, 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 haga archivos cuando reciba un error, y prefiera usar el tiempo de espera para cerrar su solicitud después de X segundos.


¡No olvides manejar los errores! El siguiente código se basa 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); }); };


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.

Edición: Gracias a @Augusto Roman por señalar que cb debe pasarse a file.close , no se debe llamar explícitamente.


Descarga usando la promesa, que resuelve un flujo legible. Ponga 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); } });


El código de Vince Yuan es genial, pero parece que está 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); }); }); }


Hablando de manejar los errores, es incluso mejor escuchar para solicitar errores también. Incluso lo validaría al verificar el código de respuesta. Aquí se considera un éxito solo para 200 códigos de respuesta, pero otros códigos pueden 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 utilizar el módulo de solicitud, ya que maneja muchos más protocolos (¡hola HTTPS!) Que no son compatibles de forma nativa con 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); }); };


La respuesta de gfxmonk tiene una carrera de datos muy estrecha entre la devolución de llamada y la finalización de file.close() . file.close() realidad toma 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 rara vez!).

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 final, los scripts ingenuos pueden terminar con un archivo incompleto. Sin programar la devolución de llamada cb través del cierre, puede obtener una carrera entre acceder al archivo y estar realmente listo.


Para aquellos que vinieron en busca de la forma basada en la promesa de 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));



Puede intentar usar res.redirect a la URL de descarga del archivo https y luego se descargará el archivo.

Me gusta: res.redirect(''https//static.file.com/file.txt'');



Ruta: img type: 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; }


Si está utilizando el método de uso expreso res.download (). De lo contrario, fs módulo de uso.

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"); } }); }


Sin biblioteca podría estar lleno de errores solo para señalar. Aquí hay algunos:

  • No se puede manejar la redirección de http, como esta URL https://calibre-ebook.com/dist/portable que es binario.
  • El módulo http no puede https url, obtendrá el Protocol "https:" not supported.

Aquí mi sugerencia:

  • Herramienta de sistema de llamadas como wget o curl
  • use alguna herramienta como node-wget-promise que también es muy fácil de usar. var wget = require(''node-wget-promise''); wget(''http://nodejs.org/images/logo.svg'');

Tal vez node.js ha cambiado, pero parece que hay algunos problemas con las otras soluciones (usando el nodo v8.1.2):

  1. No es necesario llamar a file.close() en el evento finish . Por defecto, fs.createWriteStream se establece en autoClose: https://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options
  2. file.close() debe llamarse por error. Tal vez esto no sea necesario cuando se elimine el archivo ( unlink() ), pero normalmente lo es: https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options
  3. El archivo temporal no se borra en statusCode !== 200
  4. fs.unlink() sin devolución de llamada está en desuso (advertencia de salidas)
  5. Si el archivo dest existe; está anulado

A continuación se muestra una solución modificada (que utiliza ES6 y promesas) 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); } }); }); }


Puede crear una solicitud GET HTTP y canalizar su response en una secuencia de archivos grabable:

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 desea admitir la recopilación de información en la línea de comandos, como especificar un archivo o directorio de destino o una URL, consulte algo como Commander .


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));


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); }); };


var requestModule=require("request"); requestModule(filePath).pipe(fs.createWriteStream(''abc.zip''));