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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11598274/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 06:28:47  来源:igfitidea点击:

Display Pdf in browser using express js

javascriptnode.jspdfexpressbuffer

提问by Dexter

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);
  });
});

I am a new bie to expressjs, I can't send the response with the data object. The binary content is visible in the browser. Give me suggestions how to handle this ?

我是 expressjs 的新手,我无法发送带有数据对象的响应。二进制内容在浏览器中可见。给我建议如何处理这个?

采纳答案by rdrey

I tested your code and it works for me in chrome with one change: Change app.postto app.get

我测试了你的代码,它在 chrome 中对我有用,只有一个更改:更改app.postapp.get

EDIT: since you seem to think a POST-only server is a good idea, read this: http://net.tutsplus.com/tutorials/other/a-beginners-introduction-to-http-and-rest/Scroll down until the HTTP verbs and check out the difference between GET and POST. :)

编辑:由于您似乎认为仅 POST 的服务器是个好主意,请阅读以下内容:http: //net.tutsplus.com/tutorials/other/a-beginners-introduction-to-http-and-rest/向下滚动直到 HTTP 动词并检查 GET 和 POST 之间的区别。:)

Some quick research suggests that other browsers might have other issues, IE for example might expect the URL to end in .pdf. Since I'm on my Mac I can't test that for you ;)

一些快速研究表明其他浏览器可能有其他问题,例如 IE 可能期望 URL 以.pdf. 由于我使用的是 Mac,因此无法为您测试;)

回答by AlbertEngelB

Specifying how a file download is handled all comes down to the Content-dispositionheader. You can also specify the name of the file here as well. We also set the Content-typeto ensure the browser knows what to do with the file given to it.

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

Express.js Example:

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);
});

Now if you look more closely at the Content-disposition, you'll notice the inline;field is what sets how the browser reacts to the file. If you want to force downloads, you can do so by setting inline;to attachment;

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

I've also found out (by being burnt a couple times), that if you set special characters in your filename, it can break. So I encodeURIComponent()the filename to ensure that doesn't happen.

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

Hope that helps others trying to figure out the same!

希望能帮助其他人尝试找出相同的方法!

Edit

编辑

In the time between me posting this originally and now, I've found out how to correctly encode the content-disposition's filename parameter. According to the spec, the filename should be RFC5987 encoded. I ended up finding an example code snippetfrom MDN that correctly handles the encoding here (encodeURIComponent()isn't the entirely correct format for this field).

在我最初和现在发布此内容之间的时间里,我发现了如何正确编码content-disposition's filename 参数。 根据规范,文件名应该是 RFC5987 编码的。 我最终从 MDN 中找到了一个示例代码片段,它可以正确处理此处的编码(encodeURIComponent()这不是该字段的完全正确格式)。

MDN Snippet

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);
}

Another note on top of this one, browsers don't fully comply with the spec either. Some characters will still come back incorrectly from a download (at least when I tested it).

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

You can get around thisproblem by updating how your downloads work. If your download URL ends with the filename (and you don't supply a filenameattribute in the header), it will correctly get the filename from the URL encoded value. IE 'http://subdomain.domain-url.com/some/path/to/downloads/' + encodeURIComponent("You're there, download this!.pdf")

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

Jeeze, and all to supply a file name to your downloads!

Jeeze,以及所有为您的下载提供文件名的工具!

回答by sja

My Solution for sending a PDF directly to the Browser:

我将 PDF 直接发送到浏览器的解决方案:

app.get('/my/pdf', function (req, res) {
    var doc = new Pdf();
    doc.text("Hello World", 50, 50);

    doc.output( function(pdf) {
        res.type('application/pdf');
        res.end(pdf, 'binary');
    });
});

res.end() with the second param 'binary' did the trick in my case. Otherwise express interpret it as a string

res.end() 与第二个参数“二进制”在我的情况下起到了作用。否则表示将其解释为字符串

回答by Zeeshan Hassan Memon

It is as simple as following code:

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

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');
});

For complete repo:

对于完整的回购

Clone node-cheat pdf_browser, run node appfollowed by npm install express.

克隆节点作弊pdf_browsernode app然后运行npm install express.

Happy Helping!

乐于助人!

回答by Peco

Actually Express already has this featurefor sending files. All you need is :

其实Express已经有这个发送文件的功能了。所有你需要的是 :

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

Here the server will send the file "Rabbi.pdf" and it will open in browser like you open pdf in browser. I placed the file in "static" folder but you can place it anywhere, knowing that sendFile() takes as argument the absolute path (not relative one).

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