Mostrar archivos PDF en el navegador de los usuarios a través de PHP / Perl

121

Quiero mostrar archivos PDF a mis usuarios. La razón por la que uso cgi para mostrar el pdf es que quiero rastrear los clics del pdf y ocultar la ubicación real del pdf guardado.

He estado buscando en Internet y solo encontré cómo mostrar el cuadro de diálogo de guardado a los usuarios y crear un pdf, no mostrar los archivos a los usuarios.

Lo que quería era mostrar a los usuarios mis archivos pdf, no crear ni descargar el pdf. Esto es lo que obtuve de la documentación oficial de php:

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

También mi código Perl de resultados de búsqueda de 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

si lo haces en ruby, por favor dímelo. Pero no estoy seguro de si mi servidor admite rieles.

Lo siento si mi código está demasiado lejos del método para mostrar el pdf, ya que no sé nada sobre el procesamiento de PDF y cómo implementar este problema.

Supongamos que los usuarios tienen el complemento Adobe Reader. Entonces, ¿cómo solucionar mi problema?

editar : Quiero mostrar un archivo pdf sin formato. Mi propósito principal: rastrear mis archivos pdf y usar algunas URL elegantes.

editar : Aquí está mi código php principal:

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

editar : Ahora el código está funcionando. Pero la barra de progreso de carga (en el complemento Adobe Reader X) no aparece. ¿Por qué? ¿Alguien puede ayudarme? Aquí está mi código principal:

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

editar : Todos mis problemas resueltos. Aquí está el código final:

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

¡Gracias! :)

dimassony
fuente
4
"mostrar" sólo es posible si el cliente tiene instalado el complemento Acrobat Reader. De lo contrario, siempre se servirá como un archivo de descarga, no hay nada que pueda hacer al respecto. Obscurecer la ruta del PDF también es imposible, es trivial descubrirlo. ¿Qué estás intentando hacer? Tal vez haya algunas alternativas si sabemos más sobre sus objetivos
Pekka
4
el complemento Adobe Reader solo es necesario si utiliza un navegador que no maneja archivos PDF de forma nativa. Además, si el PDF se envía al navegador a través de PHP / Perl, es muy posible ocultar la ruta real del PDF, o incluso tenerlo fuera del docroot para que no sea accesible directamente.
Stephen
1
Adobe Reader solo es necesario si el usuario está utilizando un navegador que no maneja archivos PDF de forma nativa ...
GolezTrol
@Stephen, por supuesto, es posible ocultar la ruta real, pero lo que parece querer el OP es ocultar la URL para evitar el robo.
Pekka
Supongamos que los usuarios tienen el complemento Adobe Reader. Entonces, ¿cómo solucionar mi problema?
dimassony

Respuestas:

49

Supongo que desea que el PDF se muestre en el navegador, en lugar de forzar una descarga. Si ese es el caso, intente configurar el Content-Dispositionencabezado con un valor de inline.

Recuerde también que esto también se verá afectado por la configuración del navegador: algunos navegadores pueden estar configurados para descargar siempre archivos PDF o abrirlos en una aplicación diferente (por ejemplo, Adobe Reader)

Stephen
fuente
Si. Pero cuando intento su sugerencia, aparece un error que dice "El archivo no comienza con '% PDF-'". Yo uso 'Content-Disposition: inline; filename = "the.pdf" '. ¿Cometí un error?
dimassony
4
<? php header ('Tipo de contenido: aplicación / pdf'); header ('Content-Disposition: inline; filename = "the.pdf"'); readfile ('/ dir / a / the.pdf'); ?>
dimassony
suena como que no es un archivo PDF válido?
Stephen
@Stephen Cuando abro directamente al archivo, funciona. Pero cuando utilizo la disposición de contenido en línea, no funciona.
dimassony
7
¡Es bueno escuchar y conocer la solución! Sería bueno si pudiera publicar el código final que muestre qué encabezados está enviando, para cualquier otra persona que se encuentre con esta pregunta.
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);

Probado y funciona bien. Si desea que el archivo se descargue en su lugar, reemplace

    Content-Disposition: inline

con

    Content-Disposition: attachment
Kareem
fuente
¿Por qué desactivas la compresión? ini_set ('zlib.output_compression', '0');
Enigma Plus
Porque la compresión zlib no funciona con ob_gzhandler () y este es un fragmento de código en lugar de un script completo. Ngnix maneja la compresión mejor que php. Puede usar zlib si se adapta a la configuración de su aplicación y servidor.
Kareem
4

Puede modificar un renderizador de PDF como xpdf o evince para convertirlo en una imagen gráfica en su servidor y luego entregar la imagen al usuario. Así es como funciona la vista rápida de archivos PDF de Google , los renderizan localmente y luego entregan imágenes al usuario. No hay ningún archivo PDF descargado y la fuente está bastante oculta. :)

sarnold
fuente
Esta es la única forma realmente segura de evitar el robo del documento original.
Pekka
1
No me importa el robo de documentos originales. De lo contrario, quería que los usuarios pudieran guardarlo. Además, quería bloquear algunos encabezados de clientes. Y tal vez implemente su sugerencia cuando el usuario no tenga Adobe Reader.
dimassony
Además, no sería un robo, porque el original sigue ahí.
Svante
@Svante: dudo que los propietarios de propiedad intelectual estén de acuerdo con su lógica.
ashleedawg
@ashleedawg: Dudo del apodo de "propiedad intelectual". Esto es solo una piratería de palabras para hacer que el acaparamiento de información parezca no solo un modelo comercial legítimo, sino que incluso vale la pena para el público defenderse de la innovación.
Svante
1

La forma más segura de tener una pantalla PDF en lugar de descargarla parece ser incrustarla usando un elemento objecto iframe. También hay soluciones de terceros como el visor de PDF de Google.

Consulte Mejor forma de incrustar PDF en HTML para obtener una descripción general.

También hay DoPDF , un visor de PDF en el navegador basado en Java. No puedo hablar de su calidad, pero parece interesante.

Pekka
fuente
0

También puede utilizar la clase fpdf disponible en: http://www.fpdf.org . Ofrece opciones tanto para la salida a un archivo como para la visualización en el navegador.

tapananand
fuente