Como forço a abertura de arquivos no navegador em vez de fazer o download (PDF)?

208

Existe uma maneira de forçar a abertura de arquivos PDF no navegador quando a opção "Exibir PDF no navegador" está desmarcada?

Tentei usar a tag embed e um iframe, mas ele só funciona quando essa opção está marcada.

O que eu posso fazer?

elloalisboa
fonte

Respostas:

417

Para indicar ao navegador que o arquivo deve ser exibido no navegador, a resposta HTTP deve incluir estes cabeçalhos:

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

Para que o arquivo seja baixado em vez de visualizado:

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

As aspas ao redor do nome do arquivo serão necessárias se o nome do arquivo contiver caracteres especiais, como os filename[1].pdfque de outra forma podem prejudicar a capacidade do navegador de lidar com a resposta.

Como você define os cabeçalhos de resposta HTTP dependerá do seu servidor HTTP (ou, se você estiver gerando a resposta em PDF a partir do código do servidor: sua linguagem de programação do servidor).

ColinM
fonte
13
Para forçar o download, prefiro usar o Content-Type: application / octet-stream.
Papick G. Taboada
25
@ PapickG.Taboada, mas o sistema do usuário pode não conhecer o tipo de arquivo. Por exemplo, alguns usuários podem ter optado por "Sempre abrir arquivos deste tipo" para arquivos PDF. Talvez se você deseja substituir as preferências do usuário, o octet-stream seria o caminho a seguir, mas fornecer o tipo correto e um nome de arquivo sugerido é a maneira "correta" de fornecer um download.
ColinM
2
oi @ColinM Estou um pouco confuso aqui ... estamos tendo problemas para renderizar o pdf, ele apenas fornece um texto embaralhado. onde definimos o tipo de conteúdo: application / pdf Content-Disposition: inline; "filename.pdf"? Porque nós fazemos o upload usando o código angular-js. Portanto, minha pergunta é: o tipo de conteúdo deve ser definido antes do upload? Além disso, obtemos apenas um link da equipe de back-end, um URL que fornece o caminho do arquivo, que abrimos em uma nova guia usando: window.open (url, '_blank'). Focus ();
Kailas
3
@ Kailas Eu não entendo o que você está tentando fazer .. A resposta está se referindo aos cabeçalhos que um servidor deve enviar a um cliente ao responder a uma solicitação HTTP para o arquivo PDF. Esses cabeçalhos não afetam o upload de um arquivo. É necessário que o código por trás da URL defina os cabeçalhos toda vez que o cliente faz o download.
ColinM
1
@ColinM Obrigado amigo, você disse isso certo, o problema quando depuramos foi o tipo mime que foi definido durante o upload dos arquivos. Isso deve ser feito pela equipe de back-end. Tentei obter códigos sobre como adicionar cabeçalhos no script java, mas não foi bem-sucedido. Obrigado, como eu tive a idéia real apuradas de você ... :)
Kailas
19

Se você estiver usando HTML5 (e eu acho que hoje em dia todo mundo usa isso), há um atributo chamado download.

Por exemplo,

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

Aqui filenameé opcional, mas se fornecido, esse nome será usado para o arquivo baixado.

Akshay
fonte
2
Se você tiver controle sobre o código do servidor, use 'attachement', pois isso permitirá usar o mesmo código de geração de nome de arquivo. Se você não tem controle sobre o servidor, esta é uma boa solução.
Christophe Roussy
Esta é uma solução brilhante para o problema, no entanto, como sempre, o IE está nos impedindo de usá-lo: caniuse.com/#search=download
Rory McCrossan
1
É importante observar que isso não funciona entre domínios (por exemplo, a política de mesma origem entra no caminho). Se estiver baixando de um domínio, o atributo de download não funcionará se o conteúdo estiver armazenado em um domínio diferente. O CORS pode permitir a passagem do conteúdo (não foi testado).
vol7ron
59
Este é literalmente o oposto do que o OP está pedindo :)
Chuck Le bumbum
1
Sim figurado! : \ Entendi a pergunta errada e respondi. Mas muitas pessoas chegam aqui encontrando apenas o oposto, por isso não editamos / removemos a resposta.
Akshay
16

O tipo correto é application/pdfpara PDF, não application/force-download. Parece um hack para alguns navegadores herdados. Sempre use o tipo correto de mimet, se puder.

Se você tiver controle sobre o código do servidor:

  • Download / prompt forçado: use header("Content-Disposition", "attachment; filename=myfilename.myextension");
  • O navegador tenta abri-lo: use header("Content-Disposition", "inline; filename=myfilename.myextension");

Sem controle sobre o código do servidor:

NOTA: Prefiro definir o nome do arquivo no servidor, pois você pode ter mais informações e usar código comum.

Christophe Roussy
fonte
2

Se você possui o Apache, adicione-o ao .htaccessarquivo:

<FilesMatch "\.(?i:pdf)$">
    ForceType application/octet-stream
    Header set Content-Disposition attachment
</FilesMatch>
Alex
fonte
como podemos adicionar várias extensões? Também quero adicionar a extensão DOC e XLS. Por favor, sugira-me. Desde já, obrigado.
Kamlesh
Isso faz o oposto ao que é pedido
Quentin
1

Ups! Ocorreram erros de digitação na minha postagem anterior.

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

Se você não deseja que o navegador solicite ao usuário, use "inline" para a terceira string em vez de "anexo". Inline funciona muito bem. O PDF é exibido imediatamente sem solicitar ao usuário que clique em Abrir. Eu usei "anexo" e isso solicitará ao usuário Abrir, Salvar. Tentei alterar a porca de configuração do navegador, mas isso não impede o prompt.

trangsinh1952
fonte
4
Qual post anterior?
Peter Mortensen
0

Isto é para o ASP.NET MVC

Na sua 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>

No seu 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
fonte
-1

Embora o seguinte funcione bem no Firefox, ele NÃO funciona nos navegadores Chrome e Mobile.

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

Para corrigir o erro do Chrome e dos navegadores móveis, faça o seguinte:

  • Armazene seus arquivos em um diretório em seu projeto
  • Use o visualizador de PDF do google

O Google PDF Viewer pode ser usado da seguinte maneira:

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

Abra o downloads.php no arquivo raiz.

Em seguida, vá para a linha 186 e altere-a para o seguinte:

        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
fonte
7
Sem mencionar que eles usam PHP. E se o back-end estiver em Python ou .NET?
Maxime Rouiller
1
... falar fora do campo esquerdo. Ele nem diz de que estrutura está falando.
Archonic
-4

Você pode fazer isso da seguinte maneira:

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

Se o arquivo PDF estiver dentro de alguma pasta e essa pasta não tiver permissão para acessar arquivos nessa pasta diretamente, você precisará ignorar algumas restrições de acesso a .htaccessarquivos usando a configuração de arquivos desta maneira:

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

Mas agora permita apenas alguns arquivos necessários.

Eu usei esse código e ele funcionou perfeitamente.

Mohsin
fonte
Não há menção de que eles usam Apache. E se eles usarem o IIS? Ou expresso?
Maxime Rouiller
-7

Qualquer uso

<embed src="file.pdf" />

se a incorporação for uma opção ou meu novo plug-in, PIFF: https://github.com/terrasoftlabs/piff

Gabriel Ryan Nahmias
fonte
-7

Aqui está outro método de forçar a visualização de um arquivo no navegador em 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>';
user28864
fonte
1
headernão funciona depois que você começou a produzir o corpo da solicitação (e não retorna um string para concatenar em um documento HTML)
Quentin
-9

Basta abrir o Adobe Reader, menu → EditarPreferênciasInternet e , em seguida, mudar para o modo navegador ou para obter instruções detalhadas sobre diferentes navegadores, tente Exibir PDF no navegador | Acrobat, Acrobat Reader .

Lawl
fonte
3
E se você não usar o AdobeReader ou não usar o Windows? Sua resposta não vai funcionar. Além disso, exige que o usuário altere sua configuração, o que você não pode fazer no mundo real.
Clawfire
-12

Se você vincular a um arquivo .PDF, ele será aberto no navegador.
Se a caixa estiver desmarcada, ela deve ser vinculada a um .zip para forçar o download.

Se um .zip não for uma opção, use os cabeçalhos no PHP para forçar o download

header('Content-Type: application/force-download'); 
header('Content-Description: File Transfer'); 
Kirk Strobeck
fonte
Sim, mas preciso de uma maneira de forçar a abertura no navegador para não fazer o download. Não tenho ideia se é possível.
Elloalisboa
2
Se você não está forçando o download, está forçando a abrir no navegador. Se ele não abrir no navegador, é porque o usuário possui uma configuração específica, que você não pode substituir ou que não possui um software de leitura de PDF.
Kirk Strobeck
1
Na verdade, veja minha resposta.
Gabriel Ryan Nahmias
21
Isto está errado. Não há aplicativo / download forçado. Você também pode usar alskjdsdjk / aljksdlasdj. O navegador será baixado porque não conhece esse tipo de mímica. O mime-type direita para download iria me application / octet-stream
Papick G. Taboada