Estoy tratando de descargar un archivo de otro sitio desde mi aplicación Node después de una solicitud de obtención HTTP expresa y luego devuelvo el archivo para su descarga. He intentado varias formas de obtener el archivo, usando tubería, blob, etc. pero estoy agarrando en la oscuridad. El código podría darle un poco más de información sobre lo que estoy tratando de lograr:
var router = require('express').Router(); var fs = require('fs'); var http = require('http'); router.get('/download/:file', function (req, res, next) { http.get('http://anothersite/' + req.params.file, function(response) { res.setHeader('Content-disposition', 'attachment; filename=' + req.params.file); res.setHeader('Content-type', 'application/octet-stream'); res.download(fs.createWriteStream(req.params.file).pipe(response)); }); });Esto me da un error "No se puede canalizar. No se puede leer". El archivo en sí no es un formato de archivo normal (es un archivo de nuestro software personalizado con su propia extensión).
¿Qué me estoy perdiendo?
Para uno, debe usar un flujo legible aquí, no escribible
El objeto Express res se deriva de http.ServerResponse del nodo, que a su vez implementa la interfaz WritableStream del nodo. Ver documentos aquí yaquí .
Dado que ese es el caso, creo que puede usar el argumento de response pasado a su devolución de llamada directamente, ya que ya es un ReadableStream (ver aquí ). Intente usar una secuencia legible como esta:
router.get('/download/:file', function (req, res, next) { http.get('http://anothersite/' + req.params.file, function(response) { res.setHeader('Content-disposition', 'attachment; filename=' + req.params.file); res.setHeader('Content-type', 'application/octet-stream'); response.pipe(res); // <-- change here }); });Este código funciona, con el nodo v5.0.0 y la última versión de Chrome:
const express = require('express'); const app = express(); const http = require('http'); app.get('/', (req, res) => { http.get('http://www.fillmurray.com/200/300', (response) => { res.setHeader('Content-disposition', 'attachment; filename=' + 'hello.jpg'); res.setHeader('Content-type', 'application/octet-stream'); response.pipe(res) }); }); app.listen(3001, () => console.log(('listening :)')))puede usar la biblioteca de solicitudes como: request('http://anothersite/').pipe(fs.createWriteStream('filename.extension'))
Actualizar:
Si está dispuesto a hacerlo por http, puede crear una secuencia de escritura de la siguiente manera. Después de guardar el archivo con éxito, creo que puede hacer res.download() correctamente.
var http = require('http') http.get('http://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png').on('response', function (response) { var writeStream = fs.createWriteStream('output.png'); response.pipe(writeStream); response.on('end', function () { console.log('stream completed!') }); // This is here incase any errors occur writeStream.on('error', function (err) { console.log(err); }); });