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

Javascript 使用express js在浏览器中显示Pdf,javascript,node.js,pdf,express,buffer,Javascript,Node.js,Pdf,Express,Buffer,我是expressjs的新bie,无法使用数据对象发送响应。 二进制内容在浏览器中可见。 给我一些建议如何处理这个问题?我测试了你的代码,它在chrome中对我有效,但有一个改动: 将app.post更改为app.get 编辑:既然您似乎认为POST only服务器是个好主意,请阅读以下内容: 向下滚动直到HTTP谓词出现,并查看GET和POST之间的差异。:) 一些快速研究表明,其他浏览器可能存在其他问题,例如,可能期望URL以.pdf结尾。因为我在Mac电脑上,所以无法为您测试;) 我的直接

我是expressjs的新bie,无法使用数据对象发送响应。 二进制内容在浏览器中可见。
给我一些建议如何处理这个问题?

我测试了你的代码,它在chrome中对我有效,但有一个改动: 将
app.post
更改为
app.get

编辑:既然您似乎认为POST only服务器是个好主意,请阅读以下内容: 向下滚动直到HTTP谓词出现,并查看GET和POST之间的差异。:)


一些快速研究表明,其他浏览器可能存在其他问题,例如,可能期望URL以
.pdf
结尾。因为我在Mac电脑上,所以无法为您测试;)

我的直接将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);
  });
});

res.end()和第二个参数“binary”在我的例子中起了作用。否则express将其解释为一个字符串

指定如何处理文件下载,所有这些都归结为
内容处理
标题。您还可以在此处指定文件名。我们还设置了
内容类型
,以确保浏览器知道如何处理提供给它的文件

Express.js示例: 现在,如果您更仔细地查看
内容配置
,您将注意到
内联字段用于设置浏览器对文件的反应方式。如果你想强制下载,你可以通过设置
inline
附件

我还发现(经过几次烧录),如果在文件名中设置特殊字符,它可能会崩溃。因此,我
encodeURIComponent()
文件名以确保不会发生这种情况

希望这能帮助其他人找到同样的答案

编辑 从最初发布到现在,我发现了如何正确编码
内容配置
的filename参数。我最终从MDN中找到了一个正确处理此处编码的文件(
encodeURIComponent()
不是此字段的完全正确格式)

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

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


Jeeze和所有提供文件名的下载

它就像下面的代码一样简单:

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);
}
完整回购:

克隆节点作弊,运行
节点应用程序
,然后运行
npm安装快车


乐于助人

实际上Express已经有了发送文件的功能。您所需要的只是:

var express = require('express'),
    fs = require('fs'),
    app = express();

app.get('/', function (req, res) {
    var filePath = "/files/my_pdf_file.pdf";

    fs.readFile(__dirname + filePath , function (err,data){
        res.contentType("application/pdf");
        res.send(data);
    });
});

app.listen(3000, function(){
    console.log('Listening on 3000');
});

在这里,服务器将发送文件“Rabbi.pdf”,它将在浏览器中打开,就像您在浏览器中打开pdf一样。我将文件放在“静态”文件夹中,但您可以将其放在任何位置,因为您知道sendFile()以绝对路径(而不是相对路径)作为参数。

根据Express js文档,您可以在一个函数中设置内容类型和内容配置,如下所示

app.get('/sendMePDF', function(req, res) {
  res.sendFile(__dirname + "/static/pdf/Rabbi.pdf");
})

尝试
响应。结束(数据)
;express的
send
方法可能会进行一些事后猜测。我已经添加了一个关于如何正确设置浏览器对您提供给它的文件的反应的答案。您可以在标题中设置这些内容,如果您有任何问题,请告诉我。是的,在从post更改为get后,它在我的firefox、safari、opera和chromeSo中正常工作。应用程序无法使用post吗?因为我将服务器和维护配置为只接受post请求。嗯。。。不确定为什么要将服务器配置为仅执行POST请求:浏览器可以获取您发送到的任何URL。这就是http的工作原理。:)POST通常用于表单提交,或者当您使用HTTP创建内容而不是获取内容时。公平地说,在某些用例中,您可能希望获取PDF以响应帖子。我对Node非常陌生。是什么使这种提供pdf的方法与我一直使用的sendfile(some.html)如此不同。有人能解释一下这是如何工作的吗?为什么我不必从文件系统中读取html文件?方法
doc.output
现在已被弃用。Thx!“二进制”参数真的救了我一天!只是指出一个输入错误,它应该是内容处理标题中的“附件”,而不是“附件纸”。这将在同一窗口中打开pdf文件。有没有办法在新窗口中打开它?
var express = require('express'),
    fs = require('fs'),
    app = express();

app.get('/', function (req, res) {
    var filePath = "/files/my_pdf_file.pdf";

    fs.readFile(__dirname + filePath , function (err,data){
        res.contentType("application/pdf");
        res.send(data);
    });
});

app.listen(3000, function(){
    console.log('Listening on 3000');
});
app.get('/sendMePDF', function(req, res) {
  res.sendFile(__dirname + "/static/pdf/Rabbi.pdf");
})
 fs.readFile(filePath, (err, data) => {
res.set({
  "Content-Type": "application/pdf", //here you set the content type to pdf
  "Content-Disposition": "inline; filename=" + fileName, //if you change from inline to attachment if forces the file to download but inline displays the file on the browser
});
res.send(data); // here we send the pdf file to the browser
});