¿Cómo fuerzo a los archivos a abrirse en el navegador en lugar de descargarlos (PDF)?

210

¿Hay alguna forma de forzar que los archivos PDF se abran en el navegador cuando la opción "Mostrar PDF en el navegador" está desactivada?

Intenté usar la etiqueta de inserción y un iframe, pero solo funciona cuando esa opción está marcada.

¿Que puedo hacer?

elloalisboa
fuente

Respuestas:

419

Para indicar al navegador que el archivo debe verse en el navegador, la respuesta HTTP debe incluir estos encabezados:

Content-Type: application/pdf
Content-Disposition: inline; filename="filename.pdf"

Para descargar el archivo en lugar de verlo:

Content-Type: application/pdf
Content-Disposition: attachment; filename="filename.pdf"

Las comillas alrededor del nombre del archivo son obligatorias si el nombre del archivo contiene caracteres especiales como los filename[1].pdfque, de lo contrario, pueden dañar la capacidad del navegador para manejar la respuesta.

La forma en que configure los encabezados de respuesta HTTP dependerá de su servidor HTTP (o, si está generando la respuesta PDF desde el código del lado del servidor: su lenguaje de programación del lado del servidor).

ColinM
fuente
13
Para forzar la descarga, prefiero usar Content-Type: application / octet-stream.
Papick G. Taboada
25
@ PapickG.Taboada, pero es posible que el sistema del usuario no conozca el tipo de archivo. Por ejemplo, algunos usuarios pueden haber optado por "Abrir siempre archivos de este tipo" para archivos PDF. Quizás si desea anular las preferencias del usuario, entonces octet-stream sería el camino a seguir, pero dar el tipo correcto y un nombre de archivo sugerido es la forma "correcta" de proporcionar una descarga.
ColinM
2
hola @ColinM Estoy un poco confundido aquí ... estamos teniendo problemas para renderizar el pdf, solo da un texto codificado. ¿Dónde establecemos el Tipo de contenido: application / pdf Content-Disposition: en línea; "filename.pdf"? porque lo cargamos usando el código angular-js. Entonces, mi pregunta es ¿debería establecerse el tipo de contenido antes de subir? Y también, solo obtenemos un enlace del equipo de back-end, una url que proporciona la ruta del archivo, que abrimos en una nueva pestaña usando: window.open (url, '_blank'). Focus ();
Kailas
3
@Kailas No entiendo lo que estás tratando de hacer. La respuesta se refiere a los encabezados que un servidor debe enviar a un cliente cuando responde a una solicitud HTTP para el archivo PDF. Estos encabezados no tienen ningún efecto en la carga de un archivo, debe tener el código detrás de la URL para configurar los encabezados cada vez que el cliente los descarga.
ColinM
1
@ColinM Gracias amigo, lo dijiste bien, el problema cuando depuramos fue que el tipo mime se configuró al cargar los archivos. Esto lo debe hacer el equipo de fondo. Traté de obtener códigos sobre cómo agregar encabezados en el script java pero no tuve éxito. Gracias, cuando se me ocurrió la idea real ... :)
Kailas
19

Si está usando HTML5 (y supongo que hoy en día todos lo usan), hay un atributo llamado download.

Por ejemplo,

<a href="somepathto.pdf" download="filename">

Aquí filenamees opcional, pero si se proporciona, tomará este nombre para el archivo descargado.

Akshay
fuente
2
Si tiene control sobre el código del servidor, debe usar 'adjunto' ya que esto permitirá usar el mismo código de generación de nombre de archivo. Si no tiene control sobre el servidor, esta es una buena solución.
Christophe Roussy
Esta es una solución brillante para el problema, sin embargo, como siempre, IE nos impide
Rory McCrossan
1
Es importante tener en cuenta que esto no funciona en todos los dominios (por ejemplo, la política del mismo origen se interpone). Si descarga desde un dominio, el atributo de descarga no funcionará si el contenido se almacena en un dominio diferente. CORS puede permitir que ese contenido pase (no se ha probado).
vol7ron
59
Esto es literalmente lo contrario de lo que está preguntando el OP :)
Chuck Le Butt
1
Sí figurado! : \ Entendí la pregunta mal y respondí. Pero mucha gente aterriza aquí solo encontrando lo contrario, por eso no editó / eliminó la respuesta.
Akshay
16

El tipo correcto es application/pdfpara PDF, no application/force-download. Esto parece un truco para algunos navegadores heredados. Utilice siempre el tipo MIME correcto si puede.

Si tiene control sobre el código del servidor:

  • Descarga / solicitud forzada: uso header("Content-Disposition", "attachment; filename=myfilename.myextension");
  • El navegador intenta abrirlo: usar header("Content-Disposition", "inline; filename=myfilename.myextension");

Sin control sobre el código del servidor:

NOTA: Prefiero configurar el nombre de archivo en el lado del servidor, ya que puede tener más información y puede usar un código común.

Christophe Roussy
fuente
2

Si tiene Apache, agregue esto al .htaccessarchivo:

<FilesMatch "\.(?i:pdf)$">
    ForceType application/octet-stream
    Header set Content-Disposition attachment
</FilesMatch>
Alex
fuente
¿Cómo podemos agregar múltiples extensiones? Quiero agregar DOC y la extensión XLS también. Amablemente sugiérame. Gracias por adelantado.
Kamlesh
Eso hace lo contrario de lo que se pide
Quentin
1

Vaya, hubo errores de tipeo en mi publicación anterior.

    header("Content-Type: application/force-download");
    header("Content-type: application/pdf");
    header("Content-Disposition: inline; filename=\"".$name."\";");

Si no desea que el navegador solicite al usuario, utilice "en línea" para la tercera cadena en lugar de "archivo adjunto". En línea funciona muy bien. El PDF se muestra inmediatamente sin pedirle al usuario que haga clic en Abrir. He usado "archivo adjunto" y esto le pedirá al usuario que abra, guarde. Intenté cambiar la tuerca de configuración del navegador, no evita el aviso.

trangsinh1952
fuente
44
¿Qué post anterior?
Peter Mortensen
0

Esto es para ASP.NET MVC

En su página cshtml:

<section>
    <h4><a href="@Url.Action("Download", "Document", new { id = @Model.GUID })"><i class="fa fa-download"></i> @Model.Name</a></h4>
    <object data="@Url.Action("View", "Document", new { id = @Model.GUID })" type="application/pdf" width="100%" height="800" class="col-md-12">
        <h2>Your browser does not support viewing PDFs, click on the link above to download the document.</h2>
    </object>
</section>

En tu controlador:

public ActionResult Download(Guid id)
    {
        if (id == Guid.Empty)
            return null;

        var model = GetModel(id);

        return File(model.FilePath, "application/pdf", model.FileName);
    }

public FileStreamResult View(Guid id)
    {
        if (id == Guid.Empty)
            return null;

        var model = GetModel(id);

        FileStream fs = new FileStream(model.FilePath, FileMode.Open, FileAccess.Read);

        return File(fs, "application/pdf");
    }
Leon van Wyk
fuente
-1

Si bien lo siguiente funciona bien en Firefox, NO funciona en Chrome y navegadores móviles.

Content-Type: application/pdf
Content-Disposition: inline; filename="filename.pdf"

Para corregir el error de Chrome y navegadores móviles, haga lo siguiente:

  • Almacene sus archivos en un directorio en su proyecto
  • Utilice el visor de PDF de google

Google PDF Viewer se puede usar así:

<iframe src="http://docs.google.com/gview?url=http://example.com/path/to/my/directory/pdffile.pdf&embedded=true" frameborder="0"></iframe>
Nick Kongk
fuente
-4

Abra downloads.php desde el archivo raíz.

Luego vaya a la línea 186 y cámbielo a lo siguiente:

        if(preg_match("/\.jpg|\.gif|\.png|\.jpeg/i", $name)){
            $mime = getimagesize($download_location);
            if(!empty($mime)) {
                header("Content-Type: {$mime['mime']}");
            }
        }
        elseif(preg_match("/\.pdf/i", $name)){
            header("Content-Type: application/force-download");
            header("Content-type: application/pdf");
            header("Content-Disposition: inline; filename=\"".$name."\";");
        }

        else{
            header("Content-Type: application/force-download");
            header("Content-type: application/octet-stream");
            header("Content-Disposition: attachment; filename=\"".$name."\";");
        }
Christian Felix Kazuya
fuente
77
Sin mencionar que usan PHP. ¿Qué pasa si su backend está en Python o .NET?
Maxime Rouiller
1
... hablar fuera del campo izquierdo. Ni siquiera dice de qué marco está hablando.
Archonic
-4

Puede hacer esto de la siguiente manera:

<a href="path to PDF file">Open PDF</a>

Si el archivo PDF está dentro de alguna carpeta y esa carpeta no tiene permiso para acceder a los archivos de esa carpeta directamente, entonces debe omitir algunas restricciones de acceso a .htaccessarchivos mediante la configuración de archivos de esta manera:

<FilesMatch ".*\.(jpe?g|JPE?G|gif|GIF|png|PNG|swf|SWF|pdf|PDF)$" >
    Order Allow,Deny
    Allow from all
</FilesMatch>

Pero ahora permita solo ciertos archivos necesarios.

He usado este código y funcionó perfectamente.

Mohsin
fuente
Sin mencionar que usan Apache. ¿Qué pasa si usan IIS? O expreso?
Maxime Rouiller
-7

Aquí hay otro método para forzar la visualización de un archivo en el navegador en PHP:

$extension = pathinfo($file_name, PATHINFO_EXTENSION);
$url = 'uploads/'.$file_name;
        echo '<html>'
                .header('Content-Type: application/'.$extension).'<br>'
                .header('Content-Disposition: inline; filename="'.$file_name.'"').'<br>'
                .'<body>'
                .'<object   style="overflow: hidden; height: 100%;
             width: 100%; position: absolute;" height="100%" width="100%" data="'.$url.'" type="application/'.$extension.'">
                    <embed src="'.$url.'" type="application/'.$extension.'" />
             </object>'
            .'</body>'
            . '</html>';
usuario28864
fuente
1
headerno funciona después de comenzar a generar el cuerpo de la solicitud (y no devuelve una cadena para concatenar en un documento HTML)
Quentin
-9

Simplemente abra Adobe Reader, menú → EditarPreferenciasInternet , luego cambie al modo de navegador o para obtener instrucciones detalladas sobre diferentes navegadores, intente Mostrar PDF en el navegador | Acrobat, Acrobat Reader .

lawl
fuente
3
¿Qué sucede si no usa AdobeReader o no usa Windows? Tu respuesta no funcionará. Además, requiere pedirle al usuario que cambie su configuración, lo que no puede hacer en el mundo real.
Clawfire
-12

Si vincula a un .PDF, se abrirá en el navegador.
Si la casilla no está marcada, debe vincularse a un .zip para forzar la descarga.

Si un .zip no es una opción, use encabezados en PHP para forzar la descarga

header('Content-Type: application/force-download'); 
header('Content-Description: File Transfer'); 
Kirk Strobeck
fuente
Sí, pero necesito una forma de forzar la apertura en el navegador para no descargar. No tengo idea si es posible.
elloalisboa
2
Si no está forzando que se descargue, entonces ESTÁ forzando que se abra en el navegador. Si no se abre en el navegador, es porque el usuario tiene una configuración específica, que no puede anular o no tiene un software de lectura de PDF.
Kirk Strobeck
1
En realidad, mira mi respuesta.
Gabriel Ryan Nahmias
21
Esto está mal. No hay aplicación / descarga forzada. También puede usar alskjdsdjk / aljksdlasdj. El navegador se descargará porque no conoce este tipo mime. El tipo mime correcto para descargar sería mi aplicación / flujo de octetos
Papick G. Taboada