HTTP 从不同站点获取文件并使用 Express 下载 return
HTTP Get file from different site and return with Express for download
我正在尝试在快速 HTTP get 请求后从我的 Node 应用程序下载另一个站点的文件,然后 return 文件以供下载。我尝试了多种获取文件的方法,使用管道、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));
});
});
这给我一个错误“无法通过管道传输。不可读”。该文件本身不是常规文件格式(它是来自我们自定义软件的文件,具有自己的扩展名)。
我错过了什么?
您可以将请求库用作:
request('http://anothersite/').pipe(fs.createWriteStream('filename.extension'))
更新:
如果您愿意通过 http 执行此操作,您可以创建一个写入流,如下所示。成功保存文件后,我认为您可以正确执行 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);
});
});
这里需要使用可读流,而不是可写流
Express res
对象派生自节点的 http.ServerResponse
,它本身实现了节点的 WritableStream
接口。请参阅文档 here and here.
既然是这样,我认为您可以使用直接传递给回调的 response
参数,因为它已经是 ReadableStream
(参见 here)。尝试像这样使用可读流:
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 :)')))
我正在尝试在快速 HTTP get 请求后从我的 Node 应用程序下载另一个站点的文件,然后 return 文件以供下载。我尝试了多种获取文件的方法,使用管道、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));
});
});
这给我一个错误“无法通过管道传输。不可读”。该文件本身不是常规文件格式(它是来自我们自定义软件的文件,具有自己的扩展名)。
我错过了什么?
您可以将请求库用作:
request('http://anothersite/').pipe(fs.createWriteStream('filename.extension'))
更新:
如果您愿意通过 http 执行此操作,您可以创建一个写入流,如下所示。成功保存文件后,我认为您可以正确执行 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);
});
});
这里需要使用可读流,而不是可写流
Express res
对象派生自节点的 http.ServerResponse
,它本身实现了节点的 WritableStream
接口。请参阅文档 here and here.
既然是这样,我认为您可以使用直接传递给回调的 response
参数,因为它已经是 ReadableStream
(参见 here)。尝试像这样使用可读流:
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 :)')))