Показати файли PDF у браузері користувачів через PHP / Perl


121

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

Я шукав в Інтернеті і лише дізнався, як показати діалог збереження для користувачів та створити PDF, а не показувати файли користувачам.

Те, що я хотів, - це показати користувачам мої файли pdf, а не створювати та не завантажувати PDF. Ось що я отримав з офіційної документації на php:

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

Також мій код perl google-search-result:

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

Дякую! :)


4
"показ" можливий, лише якщо у клієнта встановлений плагін Acrobat Reader. В іншому випадку він завжди буде слугувати файлом для завантаження, ви нічого не можете з цим зробити. Заглушення шляху PDF також неможливо, це неважливо дізнатися. Що намагаються зробити? Можливо, є якісь альтернативи, якщо ми дізнаємось більше про ваші цілі
Pekka

4
плагін Adobe Reader потрібен лише у тому випадку, якщо ви використовуєте веб-переглядач, який не обробляє PDF в оригінальному форматі. Крім того, якщо PDF надсилається до браузера через PHP / Perl, дуже можливо затьмарити реальний шлях до PDF або навіть мати його за межами docroot, щоб він не був доступний безпосередньо.
Стівен

1
Adobe Reader потрібен лише у тому випадку, якщо користувач використовує веб-переглядач, який не обробляє PDF-файли спочатку ...
GolezTrol

@Stephen, звичайно, можна затьмарити реальний шлях, але те, що, схоже, хоче ОП - це затьмарити URL-адресу, щоб запобігти крадіжці.
Pekka

Припустимо, що у користувачів є плагін Adobe Reader. Отже, як виправити свою проблему?
димасонія

Відповіді:


49

Я припускаю, що ви хочете, щоб PDF відображався в браузері, а не змушував його завантажувати. Якщо це так, спробуйте встановити Content-Dispositionзаголовок зі значенням inline.

Також пам’ятайте, що на це також вплинуть налаштування браузера - деякі браузери можуть бути налаштовані завжди завантажувати PDF-файли або відкривати їх у іншій програмі (наприклад, Adobe Reader)


Так. Але коли я намагаюся запропонувати вашу пропозицію, у мене з’являється помилка: «Файл не починається з«% PDF- ». Я використовую 'Content-Disposition: inline; filename = "the.pdf" '. Чи помилився я?
димасонія

4
<? php заголовок ("Тип вмісту: додаток / pdf"); заголовок ('Content-Disposition: inline; filename = "the.pdf"'); readfile ('/ dir / to / the.pdf'); ?>
димасонія

здається, що це недійсний файл PDF?
Стівен

@Stephen Коли я відкриваю право на файл, він працює. Але коли я використовую вбудований дистрибутив вмісту, він не працює.
димасонія

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, або запропонувати перетворити його на графічне зображення на вашому сервері, а потім надати зображення користувачеві. Ось так працює швидкий перегляд файлів PDF у Google , вони надають його локально, а потім доставляють зображення користувачеві. Немає завантаженого PDF-файлу, а джерело досить добре затемнено. :)


Це єдиний дійсно безпечний спосіб запобігти крадіжці оригіналу документа.
Pekka

1
Я не заперечую проти крадіжок оригіналу документа. Інакше я хотів, щоб користувачі могли його зберегти. Також я хотів заблокувати деякі заголовки клієнтів. І, можливо, я реалізую вашу пропозицію, коли у користувача немає Adobe Reader.
димасонія

Крім того, це не було б крадіжкою, бо оригінал все ще є.
Сванте

@Svante - Сумніваюся, що власники інтелектуальної власності погодились би з вашою логікою.
ashleedawg

@ashleedawg: Я сумніваюсь у "інтелектуальній власності". Це лише хакерське слово для того, щоб накопичення інформації здавалось не лише законною бізнес-моделлю, але навіть такою ж корисною для захисту населення від інновацій.
Svante

1

Найбезпечнішим способом мати дисплей PDF замість завантаження, здається, є вбудовування його за допомогою елемента objectабо iframeелемента. Існують також рішення сторонніх розробників, як-то переглядач PDF-файлів Google.

Ознайомтеся з найкращим способом вставки PDF у HTML для огляду.

Також є DoPDF , програма перегляду PDF-файлів на базі Java. Я не можу говорити про її якість, але це виглядає цікаво.


0

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.