Pokaż pliki PDF w przeglądarce użytkownika za pośrednictwem PHP / Perl


121

Chcę pokazać moim użytkownikom pliki PDF. Powodem, dla którego używam cgi do wyświetlania pliku PDF, jest to, że chcę śledzić kliknięcia pliku PDF i ukryć rzeczywistą lokalizację zapisanego pliku PDF.

Szukałem w Internecie i odkryłem tylko, jak pokazać użytkownikom okno dialogowe zapisywania i stworzyć plik PDF, a nie pokazać pliki użytkownikom.

Chciałem pokazać użytkownikom moje pliki PDF, a nie tworzyć ani pobierać pliku PDF. Oto, co otrzymałem z oficjalnej dokumentacji php:

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

Również mój kod perl wyników wyszukiwania 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

jeśli zrobisz to na rubinie, powiedz mi to. Ale nie jestem pewien, czy mój serwer obsługuje szyny.

Przepraszam, jeśli mój kod jest zbyt daleko od metody, aby wyświetlić plik PDF, ponieważ nie wiem nic o przetwarzaniu plików PDF i jak wdrożyć ten problem.

Załóżmy, że użytkownicy mają wtyczkę Adobe Reader. Jak więc rozwiązać mój problem?

edycja : chcę pokazać zwykły plik pdf. Mój główny cel: śledzenie moich plików PDF i używanie wyszukanych adresów URL.

edycja : Oto mój główny kod php:

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

edycja : Teraz kod działa. Ale pasek postępu ładowania (we wtyczce Adobe Reader X) nie pojawia się. Czemu? Czy ktoś może mi pomóc? Oto mój główny kod:

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

edycja : wszystkie moje problemy rozwiązane. Oto ostateczny kod:

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

Dzięki! :)


4
„Pokaż” jest możliwe tylko wtedy, gdy klient ma zainstalowaną wtyczkę Acrobat Reader. W przeciwnym razie zawsze będzie podawany jako plik do pobrania, nic nie możesz na to poradzić. Przesłonięcie ścieżki pliku PDF jest również niemożliwe, łatwo się dowiedzieć. Co próbujesz zrobić? Może są jakieś alternatywy, jeśli wiemy więcej o twoich celach
Pekka

4
wtyczka Adobe Reader jest wymagana tylko wtedy, gdy używasz przeglądarki, która nie obsługuje natywnie plików PDF. Ponadto, jeśli plik PDF jest wysyłany do przeglądarki przez PHP / Perl, bardzo możliwe jest zasłonięcie prawdziwej ścieżki PDF lub nawet umieszczenie go poza docrootem, aby nie był bezpośrednio dostępny.
Stephen,

1
Adobe Reader jest wymagany tylko wtedy, gdy użytkownik korzysta z przeglądarki, która natywnie nie obsługuje plików PDF ...
GolezTrol

@Stephen oczywiście można zasłonić prawdziwą ścieżkę, ale wydaje się, że OP chce zasłonić adres URL, aby zapobiec kradzieży.
Pekka,

Załóżmy, że użytkownicy mają wtyczkę Adobe Reader. Jak więc rozwiązać mój problem?
dimassony

Odpowiedzi:


49

Zakładam, że chcesz, aby plik PDF był wyświetlany w przeglądarce, zamiast wymuszać pobieranie. W takim przypadku spróbuj ustawić Content-Dispositionnagłówek na wartość inline.

Pamiętaj też, że wpłyną na to również ustawienia przeglądarki - niektóre przeglądarki mogą być skonfigurowane tak, aby zawsze pobierać pliki PDF lub otwierać je w innej aplikacji (np. Adobe Reader)


Tak. Ale kiedy wypróbowuję twoją sugestię, pojawia się komunikat o błędzie „Plik nie zaczyna się od„% PDF- ””. Używam 'Content-Disposition: inline; filename = "the.pdf" '. Czy popełniłem błąd?
dimassony

4
<? php nagłówek ('Content-type: application / pdf'); header ('Content-Disposition: inline; filename = "the.pdf"'); readfile ('/ dir / to / the.pdf'); ?>
dimassony

brzmi, jakby to nie był prawidłowy plik PDF?
Stephen

@Stephen Kiedy otwieram bezpośrednio do pliku, to działa. Ale kiedy używam wbudowanej dyspozycji treści, to nie działa.
dimassony

7
dobrze słyszeć i dobrze znać rozwiązanie! Byłoby dobrze, gdybyś mógł opublikować końcowy kod wskazujący, które nagłówki wysyłasz, dla każdego, kto napotka to pytanie.
Stephen,

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

Przetestowane i działa dobrze. Jeśli chcesz zamiast tego pobrać plik, zamień

    Content-Disposition: inline

z

    Content-Disposition: attachment

Dlaczego wyłączasz kompresję? ini_set ('zlib.output_compression', '0');
Enigma Plus

Ponieważ kompresja zlib nie działa z ob_gzhandler () i jest to fragment kodu, a nie pełny skrypt. Ngnix radzi sobie z kompresją lepiej niż php. Możesz użyć zlib, jeśli pasuje do Twojej aplikacji i konfiguracji serwera.
Kareem

4

Możesz zmodyfikować renderer PDF, taki jak xpdf lub evince, aby renderować do obrazu graficznego na serwerze, a następnie dostarczyć obraz do użytkownika. W ten sposób działa szybki podgląd plików PDF Google , renderują go lokalnie, a następnie dostarczają obrazy do użytkownika. Brak pobranego pliku PDF, a źródło jest dość dobrze ukryte. :)


To jedyny naprawdę bezpieczny sposób, aby zapobiec kradzieży oryginalnego dokumentu.
Pekka,

1
Nie mam nic przeciwko kradzieży oryginalnych dokumentów. W przeciwnym razie chciałem, aby użytkownicy mogli go zapisać. Chciałem też zablokować niektóre nagłówki klientów. A może zrealizuję twoją sugestię, gdy użytkownik nie ma programu Adobe Reader.
dimassony

Poza tym nie byłaby to kradzież, bo oryginał wciąż tam jest.
Svante

@Svante - wątpię, żeby właściciele własności intelektualnej zgodzili się z twoją logiką.
ashleedawg

@ashleedawg: Wątpię w określenie „własność intelektualna”. To tylko hakowanie słów, aby gromadzenie informacji wydawało się nie tylko legalnym modelem biznesowym, ale nawet tak samo opłacalne dla społeczeństwa, aby bronić się przed innowacjami.
Svante

1

Najbezpieczniejszym sposobem na wyświetlenie pliku PDF zamiast pobierania wydaje się być osadzenie go za pomocą elementu objectlub iframe. Istnieją również rozwiązania innych firm, takie jak przeglądarka PDF firmy Google.

Zobacz Omówienie najlepszego sposobu osadzania PDF w HTML .

Istnieje również DoPDF , oparta na Javie przeglądarka PDF w przeglądarce. Nie mogę mówić o jego jakości, ale wygląda interesująco.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.