javascript - 使用 express js 在浏览器中显示 Pdf

标签 javascript node.js pdf express buffer

我正在尝试通过 Express 以在浏览器中显示的方式提供 PDF:

app.post('/asset', function(request, response){
  var tempFile="/home/applmgr/Desktop/123456.pdf";
  fs.readFile(tempFile, function (err,data){
     response.contentType("application/pdf");
     response.send(data);
  });
});

但是,浏览器显示二进制内容。如何正确处理?

最佳答案

指定如何处理文件下载都归结为 Content-disposition header 。您也可以在此处指定文件的名称。我们还设置了 Content-type 以确保浏览器知道如何处理给它的文件。

Express.js 示例:

app.post('/url/to/hit', function(req, res, next) {
  var stream = fs.readStream('/location/of/pdf');
  var filename = "WhateverFilenameYouWant.pdf"; 
  // Be careful of special characters

  filename = encodeURIComponent(filename);
  // Ideally this should strip them

  res.setHeader('Content-disposition', 'inline; filename="' + filename + '"');
  res.setHeader('Content-type', 'application/pdf');

  stream.pipe(res);
});

现在,如果您更仔细地查看 Content-disposition,您会注意到 inline; 字段用于设置浏览器对文件的 react 方式。如果要强制下载,可以通过将 inline; 设置为 attachment;

来实现

我还发现(被烧了几次),如果您在文件名中设置特殊字符,它可能会损坏。所以我 encodeURIComponent() 文件名以确保不会发生这种情况。

希望能帮助其他人尝试解决同样的问题!

编辑

在我最初和现在发布这篇文章之间的时间里,我发现了如何正确编码 content-disposition 的文件名参数。 According to the spec, the filename should be RFC5987 encoded. 我最终找到了 example code snippet来自正确处理此处编码的 MDN(encodeURIComponent() 不是该字段的完全正确格式)。

MDN 片段

var fileName = 'my file(2).txt';
var header = "Content-Disposition: attachment; filename*=UTF-8''" 
             + encodeRFC5987ValueChars(fileName);

console.log(header); 
// logs "Content-Disposition: attachment; filename*=UTF-8''my%20file%282%29.txt"

function encodeRFC5987ValueChars (str) {
    return encodeURIComponent(str).
        // Note that although RFC3986 reserves "!", RFC5987 does not,
        // so we do not need to escape it
        replace(/['()]/g, escape). // i.e., %27 %28 %29
        replace(/\*/g, '%2A').
            // The following are not required for percent-encoding per RFC5987, 
            // so we can allow for a little better readability over the wire: |`^
            replace(/%(?:7C|60|5E)/g, unescape);
}

除此之外的另一个注意事项,浏览器也不完全符合规范。有些字符仍然会从下载中错误地返回(至少在我测试时)。

您可以通过更新下载的工作方式来解决这个问题。如果您的下载 URL 以文件名结尾(并且您没有在 header 中提供 filename 属性),它将正确地从 URL 编码值中获取文件名。 IE 'http://subdomain.domain-url.com/some/path/to/downloads/' + encodeURIComponent("你在那儿,下载这个!.pdf")

Jeeze,为您的下载提供文件名!

关于javascript - 使用 express js 在浏览器中显示 Pdf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11598274/

相关文章:

node.js - 将文件直接从 Amazon S3 (Node.js) 流式传输到客户端

javascript - 如何使整行可点击?

Javascript promise 序列

node.js - URL 中的 pump.io 端口

pdf - Open Type 字体中的字形宽度

java - 如何使用 Java 中的 PDFBOX 库查找 pdf 是纵向还是横向

pdf - 在 Latex 中包含图像时出错

javascript - React 中的事件总线?

javascript - xhr.withCredentials = true;不适用于 Chrome

javascript - 第二次运行 Node 项目需要很长时间才能加载(在 Windows 10 上)