node/express 强制浏览器下载具有自定义名称的文件

问题描述 投票:0回答:3

我为我的大学项目建立了一个节点/快速网站,在搜索法律的 ID 后,它显示一个大表,其中包含与该 ID 相关的不同格式和语言的所有文件。 我使用模块“http-proxy”来请求这些文件并将其提供给客户端。 提供 xml、xhtml、html 和 pdf 文件时没有任何问题(每个浏览器都可以直接查看它们)。 我的 .zip 和 .rdf 文件有问题。文件没有损坏,但丢失了原始名称

  • 当我单击 ZIP 图标时,它会给我下载提示,但我丢失了原始文件名(该文件将被称为“proxy”或“proxy.zip”,不同浏览器上的行为不同)
  • 当我点击RDF图标时,有些浏览器直接在浏览器中打开文件,有些浏览器无法识别该格式,有些浏览器想以“代理”名称下载它)

于是我发现了标签“a”的HTML5属性“download”。它只是解决了我的问题,无论如何,并不是每个版本的 Internet Explorer 和 Safari 都支持它。在网上冲浪时,我发现了一些解决方法,可以在 IE 或 Safari 中查看页面时在 div 链接后添加“右键单击并另存为...”,但此解决方案不适合我,因为我不是在谈论单个链接,而是一个充满链接的表格。我的网站也需要在手机上运行。

有没有办法编写一些服务器端代码来强制浏览器下载具有自定义文件名的文件?

这是代理的一小段代码:

var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({ ignorePath: true });

app.get('/proxy', function(req , res) {
    var file = req.query.file;
    var realurl = 'http://'+cfg.edb_opt.host+':'+cfg.edb_opt.port+cfg.edb_opt.rest+file;
    console.log('Proxy: serving '+realurl);
    proxy.web(req, res, { 'target': realurl });
});

所有 cfg* 变量都来自 json 配置文件,用于设置包含文件的主机、端口和起始路径。

提前致谢:)

javascript node.js express download proxy
3个回答
15
投票

您需要向响应对象添加新标头以指示文件名并进行常规下载。

res.set("Content-Disposition", "attachment;filename=somefile.ext");

如果您希望浏览器尝试在其内部打开文件,您也可以使用“内联”,就像 Chrome 浏览器打开 pdf 文件一样。

res.set("Content-Disposition", "inline;filename=somefile.ext");

根据@Thomas的建议,始终包含正确的内容类型也是一个好主意:

res.set("Content-Type", "application/octet-stream");

3
投票

在 Express 4 及更高版本中,有 2 个辅助函数可用于更改内容类型并指定附件处置:

res.type("application/octet-stream");
res.attachment("filename.ext");

请参阅文档了解

type
attachment


0
投票

处理你的前端代码。如果您已经设置,它只能以这种方式接受自定义文件名

res.setHeader('Content-Disposition', `attachment; filename='${filename}'`);

在后台。前端代码可能看起来像这样:

const withoutUserId = filename.split('_')[2];
const fileExtension = withoutUserId.split('.')[1];
const parts = withoutUserId.split('-');
const filenamePart = parts.slice(0, -1).join('-');
const downloadName = `${filenamePart}.${fileExtension}`;

然后插入生成的 blob 的 downloadName,如下所示:

a.download = downloadName;

© www.soinside.com 2019 - 2024. All rights reserved.