Pergunta

Meu aplicativo gera PDFs para consumo do usuário. O "Content-Disposition" http cabeçalho é definido como mencionado aqui . Isso é definido para "inline; filename = foo.pdf"., Que deve ser suficiente para Acrobat para dar "foo.pdf", como o nome do arquivo ao salvar o pdf

No entanto, ao clicar no botão "Salvar" no Acrobat incorporado-browser, o nome padrão para salvar não é esse nome, mas em vez disso o URL com barras alterados para sublinhados. Enorme e feio. Existe uma maneira de afetar esse nome de arquivo padrão no Adobe?

Não é uma string de consulta nos URLs, e isso não é negociável. Isto pode ser significativo, mas a adição de um "& foo = / title.pdf" ao final da URL não afeta o nome de arquivo padrão.

Update 2: Eu tentei tanto

content-disposition  inline; filename=foo.pdf
Content-Type         application/pdf; filename=foo.pdf

e

content-disposition  inline; filename=foo.pdf
Content-Type         application/pdf; name=foo.pdf

(tal como comprovado nos Firebug) Infelizmente, não funcionou.

Uma amostra de URL é

/bar/sessions/958d8a22-0/views/1493881172/export?format=application/pdf&no-attachment=true

que se traduz em um padrão Acrobat salvar como nome de arquivo

http___localhost_bar_sessions_958d8a22-0_views_1493881172_export_format=application_pdf&no-attachment=true.pdf

Update 3: Julian Reschke traz uma visão real e rigor a este caso. Por favor upvote sua resposta. Este parece ser quebrado em FF ( https://bugzilla.mozilla.org/show_bug. cgi? id = 433613 ) e IE, mas o trabalho em Opera, Safari e Chrome. http://greenbytes.de/tech/tc2231/#inlwithasciifilenamepdf

Foi útil?

Solução

Parte do problema é que o relevante RFC 2183 realmente não estado que a ver com a disposição de tipo "inline" e um nome de arquivo.

Além disso, tanto quanto eu posso dizer, a única UA que usa realmente o nome do arquivo para o tipo = linha é Firefox (veja caso de teste ).

Finalmente, não é óbvio que o plugin API realmente faz com que a informação disponível (talvez someboy familiarizado com a API pode elaborar).

Dito isto, eu enviou um ponteiro para esta pergunta a uma pessoa Adobe; talvez as pessoas certas irá dar uma olhada.

relacionadas: veja tentativa de esclarecer Content-Disposition em HTTP em projecto-Reschke-rfc2183-in-http -. este é um trabalho mais cedo em andamento, o feedback apreciado

Update: Eu adicionei um teste caso , o que parece indicar que o leitor Acrobat plugin não usar os cabeçalhos de resposta (no Firefox), embora a API plug-in fornece acesso a eles.

Outras dicas

Defina o nome do arquivo na ContentType também. Isto deve resolver o problema.

context.Response.ContentType = "application/pdf; name=" + fileName;
// the usual stuff
context.Response.AddHeader("content-disposition", "inline; filename=" + fileName);

Depois de definir cabeçalho Content-Disposition, também adicionar cabeçalho de comprimento de conteúdo, em seguida, usar BinaryWrite para transmitir o PDF.

context.Response.AddHeader("Content-Length", fileBytes.Length.ToString());
context.Response.BinaryWrite(fileBytes);

Como você, eu tentei e tentei chegar a este trabalho. Finalmente desisti dessa idéia, e apenas optou por uma solução alternativa.

Eu estou usando ASP.NET MVC Framework, então eu modifiquei meus rotas para esse controle / ação para certificar-se de que o arquivo PDF servido é a última parte da porção localização da URI (antes da string de consulta), e passar tudo o resto na cadeia de consulta.

Por exemplo:

Old URI:

http: // servidor / app / report / showpdf param1 = foo & param2 = bar & filename = myreport.pdf

New URI:

http: // servidor / app / report / showpdf / MeuRelatório. pdf? param1 = foo & param2 = bar

O cabeçalho resultante parece exatamente como o que você descreveu (tipo de conteúdo é application / pdf, disposição está em linha, filename é inutilmente parte do cabeçalho). Acrobat mostra-lo na janela do navegador (sem diálogo Salvar como) e o nome do arquivo que é preenchida automaticamente se um usuário clica no botão Acrobat Save é o nome do arquivo de relatório.

Algumas considerações:

Para que os nomes de arquivos que olhar decente, eles devem não tem nenhum caracteres de escape (isto é, sem espaços, etc) ... que é um pouco limitante. Meus nomes de arquivos são gerados automaticamente neste caso, e antes de espaços tiveram neles, que foram aparecendo como '% 20 anos na resultando Salvar nome do arquivo de diálogo. Acabei de substituir os espaços com sublinhados, e que trabalhou.

Este não é de nomes a melhor solução, mas ela não funciona. Isso também significa que você tem que ter o nome do arquivo disponível para torná-lo parte da URI original, que bagunça poder, com o fluxo de trabalho do seu programa. Se ele está sendo gerado ou recuperado a partir de um banco de dados durante a chamada do lado do servidor que gera o PDF, pode ser necessário para mover o código que gera o nome do arquivo de javascript, como parte de um envio de formulário ou se se trata de um banco de dados torná-lo um chamada ajax rápida de obter o nome do arquivo ao construir o URL que resulta no PDF inline.

Se você está tomando o nome do arquivo a partir de uma entrada do usuário em um formulário, em seguida, que deve ser validado não contêm caracteres de escape, que vai incomodar os usuários.

Espero que ajude.

Tente colocar o nome do arquivo no final do URL, antes de quaisquer outros parâmetros. Isso funcionou para mim. http://www.setasign.de/support/ tips-and-tricks / filename-in-browser-plugin /

Em ASP.NET 2.0 alterar o URL de

http://www. server.com/DocServe.aspx?DocId=XXXXXXX

para

http://www. server.com/DocServe.aspx/MySaveAsFileName?DocId=XXXXXXX

Isso funciona para o Acrobat 8 ??e o nome do arquivo SaveAs padrão agora é MySaveAsFileName.pdf.

No entanto, você tem que restringir os caracteres permitidos em MySaveAsFileName (sem períodos, etc.).

mod_rewrite do Apache pode resolver isso.

Eu tenho um serviço web com um ponto final na /foo/getDoc.service. Claro Acrobat irá salvar arquivos como getDoc.pdf. Eu adicionei as seguintes linhas em apache.conf:

LoadModule     RewriteModule         modules/mod_rewrite.so
RewriteEngine  on
RewriteRule    ^/foo/getDoc/(.*)$    /foo/getDoc.service     [P,NE]

Agora, quando eu solicitar /foo/getDoc/filename.pdf?bar&qux, ele é reescrito internamente para /foo/getDoc.service?bar&qux, então eu estou batendo o ponto de extremidade correto do serviço web, mas Acrobat acha que vai salvar meu arquivo como filename.pdf.

Se você usar asp.net, você pode controlar pdf filename através nome do arquivo página (url). Como outros usuários escreveu, Acrobat é um pouco s ... quando se escolher o nome do arquivo pdf quando você pressionar botão "Salvar": leva o nome da página, remove a extensão e adicionar ".pdf". Então /foo/bar/GetMyPdf.aspx dá GetMyPdf.pdf.

A única solução que eu encontrei é o de gerir "dinâmicos" nomes de página através de um manipulador de asp.net:

  • criar uma classe que implementa IHttpHandler
  • mapear um manipulador no web.config limitada à classe

Mapping1: todas as páginas têm uma raiz comum (MyDocument _):

<httpHandlers>  
<add verb="*" path="MyDocument_*.ashx" type="ITextMiscWeb.MyDocumentHandler"/>

Mapping2: nome do arquivo completamente livre (precisa de uma pasta no caminho):

<add verb="*" path="/CustomName/*.ashx" type="ITextMiscWeb.MyDocumentHandler"/>

Algumas dicas aqui (o pdf é criado dinamicamente usando iTextSharp):
http: // fhtino. blogspot.com/2006/11/how-to-show-or-download-pdf-file-from.html

Em vez de anexo que você pode tentar em linha:

Response.AddHeader("content-disposition", "inline;filename=MyFile.pdf");

I usado em linha em uma aplicação web anterior que gerou saída Crystal Reports em PDF e enviados que no navegador para o usuário.

diálogo de download de arquivo (PDF) com Salvar e opção aberta

Pontos para lembrar:

  1. Voltar Stream com o tamanho da matriz correta do serviço
  2. Leia o arrary byte do fluxo com comprimento de byte correta com base no comprimento do fluxo.
  3. set contenttype correta

Aqui está o código para o fluxo de leitura e abrir o diálogo de download de arquivo para arquivo PDF

private void DownloadSharePointDocument()
{
    Uri uriAddress = new Uri("http://hyddlf5187:900/SharePointDownloadService/FulfillmentDownload.svc/GetDocumentByID/1/drmfree/");
    HttpWebRequest req = WebRequest.Create(uriAddress) as HttpWebRequest;
    // Get response   
    using (HttpWebResponse httpWebResponse = req.GetResponse() as HttpWebResponse)
    {
        Stream stream = httpWebResponse.GetResponseStream();
        int byteCount = Convert.ToInt32(httpWebResponse.ContentLength);
        byte[] Buffer1 = new byte[byteCount];
        using (BinaryReader reader = new BinaryReader(stream))
        {
            Buffer1 = reader.ReadBytes(byteCount);
        }
        Response.Clear();
        Response.ClearHeaders();
        // set the content type to PDF 
        Response.ContentType = "application/pdf";
        Response.AddHeader("Content-Disposition", "attachment;filename=Filename.pdf");
        Response.Buffer = true;
        Response.BinaryWrite(Buffer1);
        Response.Flush();
       // Response.End();
    }
}

Eu acredito que isto já foi mencionado em um sabor ou de outra, mas vou tentar e estado em minhas próprias palavras.

Ao contrário do que isto:

/bar/sessions/958d8a22-0/views/1493881172/export?format=application/pdf&no-attachment=true

Eu uso este:

/bar/sessions/958d8a22-0/views/1493881172/NameThatIWantPDFToBe.pdf?GeneratePDF=1

Ao invés de ter processo de "exportar" o pedido, quando uma solicitação é recebida, eu olho no URL para GeneratePDF = 1. Se encontrado, eu corro qualquer código que foi executado em "exportar" em vez de permitir o meu sistema para tentar procurar e servir a um PDF no /bar/sessions/958d8a22-0/views/1493881172/NameThatIWantPDFToBe.pdf localização. Se GeneratePDF não é encontrado na URL, eu simplesmente transmitir o arquivo solicitado. (Note que eu não posso simplesmente redirecionar para o arquivo solicitado - ou então eu ia acabar em um loop infinito)

Você pode sempre ter dois links. Um que abre o documento dentro do navegador, e outro para baixá-lo (usando um tipo de conteúdo incorreto). Isto é o que o Gmail faz.

Para quem ainda olhando para isso, usei a solução encontrada aqui e funcionou maravilhosamente. Graças Fabrizio!

A maneira que eu resolvi esse (com PHP) é a seguinte:

Suponha que a sua URL é SomeScript.php?id=ID&data=DATA e o arquivo que você deseja usar é TEST.pdf.

Alterar o URL para SomeScript.php/id/ID/data/DATA/EXT/TEST.pdf.

É importante que o último parâmetro é o nome do arquivo que você quer Adobe para usar (o 'EXT' pode ser sobre qualquer coisa). Certifique-se não há caracteres especiais na string acima, BTW.

Agora, no topo da SomeScript.php, adicione:

$_REQUEST = MakeFriendlyURI( $_SERVER['PHP\_SELF'], $_SERVER['SCRIPT_FILENAME']);

Em seguida, adicione esta função para SomeScript.php (ou sua biblioteca de função):

function MakeFriendlyURI($URI, $ScriptName) {

/* Need to remove everything up to the script name */
$MyName = '/^.*'.preg_quote(basename($ScriptName)."/", '/').'/';
$Str = preg_replace($MyName,'',$URI);
$RequestArray = array();

/* Breaks down like this
      0      1     2     3     4     5
    PARAM1/VAL1/PARAM2/VAL2/PARAM3/VAL3
*/

$tmp = explode('/',$Str);   
/* Ok so build an associative array with Key->value
   This way it can be returned back to $_REQUEST or $_GET
 */
for ($i=0;$i < count($tmp); $i = $i+2){
    $RequestArray[$tmp[$i]] = $tmp[$i+1];
}
return $RequestArray;       
}//EO MakeFriendlyURI

Agora $_REQUEST (ou $_GET se você preferir) é acessado como $_REQUEST['id'] normal, $_REQUEST['data'], etc.

E Adobe irá utilizar o seu nome do arquivo desejado como padrão salvar como ou info-mail quando você envia-lo em linha.

Eu estava redirecionado aqui porque eu tenho o mesmo problema. Eu também tentei solução de Troy Howard mas é não parece trabalho.

A abordagem que eu fiz em um presente é para não mais objeto de resposta uso para gravar o arquivo na mosca. Desde o PDF já está existente no servidor, o que eu fiz foi para redirecionar minha página apontando para o arquivo PDF. Funciona muito bem.

http://forums.asp.net/t/143631.aspx

Espero que minha explicação vaga deu-lhe uma idéia.

Créditos para Vivek .


Nginx

location /file.pdf
{
    # more_set_headers "Content-Type: application/pdf; name=save_as_file.pdf";
    add_header Content-Disposition "inline; filename=save_as_file.pdf";
    alias /var/www/file.pdf;
}

Verifique com

curl -I https://example.com/file.pdf

O Firefox 62.0b5 (64-bit): Ok.

Chrome 67.0.3396.99 (64-Bit): Ok.

IE. 11: Nenhum comentário

Tente isso, se o seu executável é "get.cgi"

http: //server,org/get.cgi/filename .pdf arquivo? = filename.pdf

Sim, é completamente insano. Não há nenhum arquivo chamado "filename.pdf" no servidor, não é o diretório em tudo sob o get.cgi executável.

Mas parece trabalho. O servidor ignora o filename.pdf eo leitor pdf ignora o "get.cgi"

Dan

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top