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);
});
});
我是表达js的新bie,我不能用数据对象发送响应。 二进制内容在浏览器中可见。 给我建议如何处理这个?
答案 0 :(得分:25)
指定文件下载的处理方式都归结为Content-disposition
标题。您也可以在此处指定文件的名称。我们还设置Content-type
以确保浏览器知道如何处理提供给它的文件。
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;
字段设置了浏览器对文件的反应。如果您想强制下载,可以将inline;
设置为attachment;
我也发现了(烧了几次),如果你在你的文件名中设置特殊字符,它就会破坏。所以我encodeURIComponent()
文件名以确保不会发生。
希望能帮助其他人试图找出相同的东西!
在我最初和现在发布之间的时间里,我发现了如何正确编码content-disposition
的文件名参数。 According to the spec, the filename should be RFC5987 encoded. 我最终从MDN中找到了example code snippet,正确处理了此处的编码(encodeURIComponent()
不是此字段的完全正确格式。)
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以文件名结尾(并且您没有在标头中提供filename
属性),它将从URL编码值正确获取文件名。 IE 'http://subdomain.domain-url.com/some/path/to/downloads/' + encodeURIComponent("You're there, download this!.pdf")
Jeeze,以及为您的下载提供文件名的所有内容!
答案 1 :(得分:10)
我将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()与第二个参数'二进制'在我的情况下做了伎俩。否则表达将其解释为字符串
答案 2 :(得分:8)
我测试了你的代码,它在chrome中适用于我,只有一个变化:
将app.post
更改为app.get
编辑:既然你认为只有POST服务器是个好主意,请阅读:http://net.tutsplus.com/tutorials/other/a-beginners-introduction-to-http-and-rest/ 向下滚动直到HTTP动词并检查GET和POST之间的区别。 :)
一些快速研究表明,其他浏览器可能还有其他问题,例如IE可能希望URL以.pdf
结尾。由于我在Mac上,我无法为你测试;)
答案 3 :(得分:4)
就像下面的代码一样简单:
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');
});
完整的回购:
克隆节点作弊pdf_browser,运行node app
后跟npm install express
。
快乐帮助!
答案 4 :(得分:0)
实际上Express具有将文件发送到远程的功能。您只需要:
app.get('/sendMePDF', function(req, res) {
res.sendFile(__dirname + "/static/pdf/Rabbi.pdf");
})
在这里服务器将发送文件“ Rabbi.pdf”,它将像在浏览器中打开pdf一样在浏览器中打开。我将文件放置在“静态”文件夹中,但您可以将其放置在任何位置,因为sendFile()会将绝对路径(而不是相对路径)作为参数。
答案 5 :(得分:0)
根据 Express js 文档,您可以在一个函数中设置内容类型和内容配置,如下所示
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
});