Отображение Pdf в браузере с помощью express js
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);
});
});
Я новый bie для expressjs, я не могу отправить ответ с объектом данных.
Бинарный контент отображается в браузере.
Дайте мне советы, как справиться с этим?
Ответы
Ответ 1
Я проверил ваш код, и он работает для меня в хроме с одним изменением:
Измените app.post
на app.get
EDIT: поскольку вы, кажется, думаете, что сервер POST-only - хорошая идея, прочитайте следующее: http://net.tutsplus.com/tutorials/other/a-beginners-introduction-to-http-and-rest/
Прокрутите вниз до HTTP-глаголов и проверьте разницу между GET и POST.:)
Некоторые быстрые исследования показывают, что другие браузеры могут иметь другие проблемы, например, IE может ожидать, что URL-адрес закончится в .pdf
. Поскольку я нахожусь на своем Mac, я не могу проверить это для вас;)
Ответ 2
Указание того, как обрабатывается загрузка файла, сводится к заголовку Content-disposition
. Вы также можете указать имя файла здесь. Мы также устанавливаем Content-type
, чтобы браузер знал, что делать с предоставленным ему файлом.
Экспресс .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;
определяет, как браузер реагирует на файл. Если вы хотите принудительно загружать файлы, вы можете сделать это, установив inline;
в attachment;
Я также узнал (будучи сожженным пару раз), что если вы установите специальные символы в своем имени файла, это может сломаться. Поэтому я encodeURIComponent()
имя файла, чтобы этого не произошло.
Надеюсь, что помогает другим пытаться понять то же самое!
Изменить
В то время, когда я отправлял это изначально и сейчас, я выяснил, как правильно кодировать параметр Content-disposition
filename. Согласно спецификации, имя файла должно быть закодировано RFC5987. Я закончил поиск фрагмента кода кода из 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-адрес загрузки заканчивается с именем файла (и вы не добавляете атрибут filename
в заголовок), он будет правильно получать имя файла из кодированного значения URL. IE 'http://subdomain.domain-url.com/some/path/to/downloads/' + encodeURIComponent("You're there, download this!.pdf")
Jeeze, и все, чтобы указать имя файла для ваших загрузок!
Ответ 3
Мое решение для отправки 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() со вторым параметром 'binary' сделал трюк в моем случае. В противном случае выражение интерпретирует его как строку
Ответ 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');
});
Для полного репо:
Клон node -cheat pdf_browser, запустите node app
, а затем npm install express
.
Счастливая помощь!
Ответ 5
На самом деле экспресс имеет функцию для отправки файлов на удаленный. Все, что тебе нужно:
app.get('/home', function(req, res) {
res.sendFile(__dirname + "/static/pdf/Rabbi.pdf");
})
Здесь сервер отправит файл "Rabbi.pdf", и он откроется в браузере так же, как вы открываете pdf в браузере. Я поместил файл в "статическую" папку, но вы можете разместить его где угодно, зная, что sendFile() принимает в качестве аргумента абсолютный путь (а не относительный).