HTTP从不同的站点获取文件,并以Express下载

我试图从我的节点应用程序下载一个文件,在一个明确的HTTP请求后,然后返回文件下载。 我已经尝试了多种获取文件的方式,使用pipe道,blob等,但我在黑暗中抓取,我需要一些帮助。 代码可能会让你更深入地了解我正在努力实现的目标:

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

这给我一个错误“不能pipe。不可读”。 该文件本身不是一个常规的文件格式(这是一个来自我们的定制软件,具有自己的扩展名的文件)。

我错过了什么? 任何有识之士将超级赞赏!

谢谢

对于你需要在这里使用可读stream,不可写

Express res对象是从节点的http.ServerResponse派生的,它本身实现节点的WritableStream接口。 请参阅这里和这里的文档。

既然是这样,我想你可以直接使用传递给你的callback函数的response参数,因为这已经是一个ReadableStream (见这里 )。 尝试使用这样的可读stream:

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

此代码正在工作,使用节点v5.0.0和最新的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 :)'))) 

你可以使用请求库: request('http://anothersite/').pipe(fs.createWriteStream('filename.extension'))

更新:

如果你愿意这样做,你可以创build一个写入stream如下。 成功保存文件后,我认为你可以正确地做res.download()

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