res.attachment 确实将字符串作为其唯一参数,但该字符串用作向浏览器提示用户决定保存文件时文件名应该是什么。它不允许您指定要获取的 URL 或文件名。
因为你没有发送任何数据(res.send() 没有缓冲区或.write() 调用),只是关于文件名应该是什么的建议,下载是 0 字节。
你可以做的是pipe a HTTP request to res,它会让你的服务器下载并转发文件。该文件不会缓存在您的服务器上,并且会“消耗”上传和下载容量(但没有存储空间)。
关于如何将 HTTPS 请求通过管道传输到响应的示例。
您可以使用许多其他库来代替 Node 的内置 https.request。它们中的大多数都支持流文件。这些库可以更轻松地处理错误。
const express = require('express');
const https = require('https');
const app = express();
const url = 'https://full-url-to-your/remote-file.pdf';
const headerAllowList = [
'content-type', 'content-length', 'last-modified', 'etag'
];
app.use('/', async (req, res, next) => {
// Create a HTTPS request
const externalRequest = https.request(url, {
headers: {
// You can add headers like authorization or user agent strings here.
// Accept: '*/*',
// 'User-Agent': '',
},
}, (externalResponse) => {
// This callback won't start until `.end()` is called.
// To make life easier on ourselves, we can copy some of the headers
// that the server sent your Node app and pass them along to the user.
headerAllowList
.filter(header => header in externalResponse.headers)
.forEach(header => res.set(header, externalResponse.headers[header]));
// If we didn't have content-type in the above headerAllowList,
// you could manually tell browser to expect a PDF file.
// res.set('Content-Type', 'application/pdf');
// Suggest a filename
res.attachment('some-file.pdf');
// Start piping the ReadableStream to Express' res.
externalResponse.pipe(res);
});
externalRequest.on('error', (err) => {
next(err);
});
// Start executing the HTTPS request
externalRequest.end();
});
app.listen(8000);
如果您访问 localhost:8000,您将收到一个 PDF,其中包含一个带有建议文件名的保存文件对话框,从指定的 URL 提供。