Показывать файлы PDF в браузере пользователей через PHP / Perl

121

Я хочу показать своим пользователям PDF-файлы. Причина, по которой я использую cgi для отображения PDF-файла, заключается в том, что я хочу отслеживать клики для PDF-файла и скрывать реальное местоположение сохраненного PDF-файла.

Я искал в Интернете и нашел только, как показать диалог сохранения пользователям и создать PDF-файл, а не показывать файлы пользователям.

Я хотел показать пользователям мои файлы pdf, а не создавать и не скачивать их. Вот что я получил из официальной документации php:

<?php
header('Content-type: application/pdf');
readfile('the.pdf');
?>

Также мой код Perl для результатов поиска в Google:

open(PDF, "the.pdf") or die "could not open PDF [$!]";
binmode PDF;
my $output = do { local $/; <PDF> };
close (PDF);

print "Content-Type: application/pdf\n";
print "Content-Length: " .length($output) . "\n\n";
print $output

если ты сделаешь это на рубине, скажи мне, пожалуйста. Но я не уверен, поддерживает ли мой сервер рельсы.

Извините, если мой код слишком далек от метода, чтобы показать pdf, так как я ничего не знаю об обработке pdf и о том, как реализовать эту проблему.

Предположим, что у пользователей есть плагин Adobe Reader. Итак, как исправить мою проблему?

изменить : я хочу показать простой файл PDF. Моя основная цель: отслеживать мои файлы pdf и использовать несколько причудливых URL-адресов.

изменить : Вот мой основной код PHP:

<?php
$file='/files/the.pdf';
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="the.pdf"');
@readfile($file);
?>

изменить : теперь код работает. Но индикатор выполнения загрузки (в плагине Adobe Reader X) не отображается. Зачем? Кто-нибудь может мне помочь? Вот мой основной код:

<?php
$file='./files/the.pdf';
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="the.pdf"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
@readfile($file);
?>

изменить : все мои проблемы решены. Вот последний код:

<?php
$file = './path/to/the.pdf';
$filename = 'Custom file name for the.pdf'; /* Note: Always use .pdf at the end. */

header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
header('Accept-Ranges: bytes');

@readfile($file);
?>

Спасибо! :)

dimassony
источник
4
"показать" возможно только в том случае, если на клиенте установлен плагин Acrobat Reader. В противном случае он всегда будет использоваться как файл для загрузки, с этим ничего не поделать. Скрыть путь к PDF-файлу тоже невозможно, это тривиально выяснить. Что пытаетесь сделать? Может быть, есть альтернативы, если мы больше узнаем о ваших целях
Пекка
4
подключаемый модуль Adobe Reader требуется только в том случае, если вы используете браузер, который изначально не поддерживает файлы PDF. кроме того, если PDF-файл отправляется в браузер через PHP / Perl, очень возможно скрыть реальный путь PDF-файла или даже оставить его вне корневого каталога, чтобы он не был доступен напрямую.
Стивен
1
Adobe Reader требуется только в том случае, если пользователь использует браузер, который изначально не поддерживает PDF-файлы ...
GolezTrol
@Stephen, конечно, можно скрыть реальный путь, но OP, похоже, хочет скрыть URL-адрес, чтобы предотвратить кражу.
Pekka
Предположим, что у пользователей есть плагин Adobe Reader. Итак, как исправить мою проблему?
dimassony

Ответы:

49

Я предполагаю, что вы хотите, чтобы PDF-файл отображался в браузере, а не принудительно загружал. В этом случае попробуйте установить Content-Dispositionзаголовок со значением inline.

Также помните, что это также будет зависеть от настроек браузера - некоторые браузеры могут быть настроены так, чтобы всегда загружать файлы PDF или открывать их в другом приложении (например, Adobe Reader).

Стивен
источник
Да. Но когда я пробую ваше предложение, я получаю сообщение об ошибке: «Файл не начинается с '% PDF-'». Я использую Content-Disposition: inline; имя файла = "the.pdf". Я сделал ошибку?
dimassony
4
<? php header ('Content-type: application / pdf'); заголовок ('Content-Disposition: inline; filename = "the.pdf"'); ReadFile ( '/ реж / к / the.pdf'); ?>
dimassony
звучит так, будто это недействительный файл PDF?
Стивен
@Stephen Когда я открываю прямо к файлу, он работает. Но когда я использую встроенную диспетчеризацию контента, это не работает.
dimassony
7
приятно слышать, и приятно знать решение! Было бы хорошо, если бы вы могли опубликовать окончательный код, показывающий, какие заголовки вы отправляете, для всех, кто сталкивается с этим вопросом.
Стивен
18
    $url ="https://yourFile.pdf";
    $content = file_get_contents($url);

    header('Content-Type: application/pdf');
    header('Content-Length: ' . strlen($content));
    header('Content-Disposition: inline; filename="YourFileName.pdf"');
    header('Cache-Control: private, max-age=0, must-revalidate');
    header('Pragma: public');
    ini_set('zlib.output_compression','0');

    die($content);

Протестировано и работает нормально. Если вы хотите, чтобы файл загружался, замените

    Content-Disposition: inline

с участием

    Content-Disposition: attachment
Карима
источник
Почему ты отключаешь сжатие? ini_set ( 'zlib.output_compression', '0');
Enigma Plus,
Поскольку сжатие zlib не работает с ob_gzhandler (), и это скорее фрагмент кода, чем полный сценарий. Ngnix обрабатывает сжатие лучше, чем php. Вы можете использовать zlib, если он подходит для вашего приложения и настройки сервера.
Карим
4

Вы можете изменить средство визуализации PDF, такое как xpdf или evince, для визуализации в графическое изображение на вашем сервере, а затем доставить изображение пользователю. Вот как работает быстрый просмотр файлов PDF в Google: они визуализируют его локально, а затем доставляют изображения пользователю. Нет загруженного файла PDF, и источник довольно хорошо скрыт. :)

sarnold
источник
Это единственный действительно безопасный способ предотвратить кражу исходного документа.
Pekka
1
Я не возражаю против кражи оригинального документа. В противном случае я хотел, чтобы пользователи могли его сохранять. Также я хотел заблокировать некоторые заголовки клиентов. И, возможно, я воплощу ваше предложение, когда у пользователя нет Adobe Reader.
dimassony
К тому же это не было бы кражей, потому что оригинал все еще там.
Svante
@Svante - Сомневаюсь, что владельцы интеллектуальной собственности согласятся с вашей логикой.
ashleedawg
@ashleedawg: Я сомневаюсь в прозвище «интеллектуальная собственность». Это всего лишь слово «взломать», чтобы накопление информации выглядело не только как законная бизнес-модель, но и как полезная общественность для защиты от инноваций.
Svante
1

Самый безопасный способ отображения PDF вместо загрузки - это встраивание его с помощью элемента objectили iframe. Существуют также сторонние решения, такие как программа просмотра PDF от Google.

См. Обзор Лучший способ встраивания PDF в HTML .

Также существует DoPDF , программа просмотра PDF в браузере на основе Java. Не могу сказать о качестве, но выглядит интересно.

Пекка
источник
0

Вы также можете использовать класс fpdf, доступный по адресу: http://www.fpdf.org . Он предоставляет параметры как для вывода в файл, так и для отображения в браузере.

tapananand
источник