“名称”网页pdf更好的默认保存文件名在Acrobat中?

我的应用程序生成PDF用户消费。 “Content-Disposition”http头部设置如上所述。 这被设置为“inline; filename = foo.pdf”,这应该足以让Acrobat在保存pdf时将“foo.pdf”作为文件名。

但是,在浏览器embedded式Acrobat中单击“保存”button后,保存的默认名称不是该文件名,而是带有斜线的URL更改为下划线。 巨大而丑陋。 有没有办法在Adobe中影响这个默认文件名?

在URL中有一个查询string,这是不可协商的。 这可能很重要,但在URL的末尾添加“&foo = / title.pdf”不会影响默认文件名。

更新2:我已经尝试了两个

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

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

(通过萤火虫validation)可悲的是,既没有工作。

示例url是

  /酒吧/会议/ 958d8a22-0 /视图/ 1493881172 /出口?格式=应用程序/ PDF和无附件=真 

这转换为一个默认的Acrobat保存为文件名

  HTTP ___ localhost_bar_sessions_958d8a22-0_views_1493881172_export_format = application_pdf&没有附着= true.pdf 

更新3:Julian Reschke给这个案例带来了真正的洞察力和严谨性。 请提出他的答案。 这似乎是在FF( https://bugzilla.mozilla.org/show_bug.cgi?id=433613 )和IE浏览器,但在Opera,Safari和Chrome工作。 http://greenbytes.de/tech/tc2231/#inlwithasciifilenamepdf

部分问题是相关的RFC 2183并没有真正说明如何处理types为“inline”和文件名。

此外,据我所知,实际使用type = inline的文件名的唯一UA是Firefox(请参阅testing用例 )。

最后,插件API实际上可以提供这些信息并不是很明显(也许某些熟悉API的人可以详细说明)。

话虽如此,我已经把一个指向这个问题的指针给了一个Adobe人, 也许正确的人会看看。

相关内容:请参阅draft-reschke-rfc2183-in-http中的尝试阐明HTTP中的内容处置 – 这是早期的工作,反馈表示赞赏。

更新:我已经添加了一个testing用例 ,这似乎表明Acrobat Reader插件不使用响应标头(在Firefox中),虽然插件API提供了对它们的访问。

像你一样,我努力尝试着让这个工作。 最后,我放弃了这个想法,并select了一个解决方法。

我正在使用ASP.NET MVC框架,所以我修改了我的路由控制器/操作,以确保提供的PDF文件是URI的位置部分的最后一部分(查询string之前),并通过一切否则在查询string中。

例如:

旧的URI:

HTTP://服务器/应用程序/报告/ showpdf参数1 =富&参数2 =酒吧和文件名= myreport.pdf

新的URI:

HTTP://server/app/report/showpdf/myreport.pdf参数1 =富&参数2 =酒吧

结果的标题看起来完全像你所描述的(内容types是application / pdf,处置是内联的,文件名是无用的标题的一部分)。 Acrobat在浏览器窗口中显示它(不保存为对话框),如果用户点击Acrobat保存button,自动填充的文件名是报告文件名。

几点考虑:

为了文件名看起来不错,他们不应该有任何转义的字符(即没有空格等)…这是有点限制。 我的文件名在这种情况下是自动生成的,之前在它们中有空格,在结果保存对话框文件名中显示为'%20'。 我只是用下划线replace空格,然后解决了。

这是没有名字的最好的解决scheme,但它确实有效。 这也意味着你必须有可用的文件名,使其成为原始URI的一部分,这可能会混淆你的程序的工作stream程。 如果在生成PDF的服务器端调用期间,它正在生成或从数据库中检索,则可能需要将生成文件名的代码作为表单提交的一部分移至javascript,或者如果它来自数据库,则将其作为快速ajax调用获取文件名时,build立的内联PDF导致的URL。

如果您从表单上的用户input中获取文件名,那么应该validation其不包含转义字符,这会惹恼用户。

希望有所帮助。

ContentType中也设置文件名称 。 这应该解决问题。

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

设置content-disposition标题后,还要添加content-length标题,然后使用二进制写入来stream式传输PDF。

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

在ASP.NET 2.0中更改URL

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

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

这适用于Acrobat 8​​,默认的SaveAs文件名现在是MySaveAsFileName.pdf

但是,您必须限制MySaveAsFileName允许的字符(无句点等)。

Apache的mod_rewrite可以解决这个问题。

我有一个端点在/foo/getDoc.service的Web服务。 当然,Acrobat会将文件保存为getDoc.pdf 。 我在apache.conf添加了以下几行:

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

现在,当我请求/foo/getDoc/filename.pdf?bar&qux ,它被内部重写为/foo/getDoc.service?bar&qux ,所以我正在打击Web服务的正确端点,但Acrobat认为它会保存我的文件作为filename.pdf

尝试将该文件的名称放在URL的末尾,然后再放入任何其他参数。 这对我有效。 http://www.setasign.de/support/tips-and-tricks/filename-in-browser-plugin/

如果您使用asp.net,则可以通过页面(url)文件名来控制pdf文件名。 其他用户写道,Acrobat是有点s …当您按下“保存”button时,selectPDF文件的名称:它采取页面名称,删除扩展名,并添加“.pdf”。 所以/foo/bar/GetMyPdf.aspx给GetMyPdf.pdf。

我find的唯一解决scheme是通过一个asp.net处理程序pipe理“dynamic”页面名称:

  • 创build一个实现IHttpHandler的类
  • 在web.config中映射一个绑定到该类的处理程序

Mapping1:所有页面都有一个共同的基数(MyDocument_):

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

Mapping2:完全免费的文件名(需要path中的文件夹):

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

这里有一些提示(pdf是使用iTextSharpdynamic创build的):
http://fhtino.blogspot.com/2006/11/how-to-show-or-download-pdf-file-from.html

您可以尝试内联,而不是附件:

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

我在以前的Web应用程序中使用内联,将Crystal Reports输出生成为PDF,并将其发送到用户。

文件下载对话框(PDF)与保存和打开选项

记住要点:

  1. 从服务返回正确数组大小的stream
  2. 根据stream的长度从正确的字节长度stream中读取字节。
  3. 设置正确的内容types

这里是读取stream的代码,并打开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(); } } 

我相信这已经被提到了一种或另一种味道,但我会尝试用我自己的话说出来。

而不是:

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

我使用这个:

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

而不是“导出”处理请求,当请求进入时,我查看GeneratePDF = 1的URL。 如果find,我将运行“导出”中运行的任何代码,而不允许我的系统尝试在位置/bar/sessions/958d8a22-0/views/1493881172/NameThatIWantPDFToBe.pdfsearch和提供PDF。 如果在URL中找不到GeneratePDF,我只需传输所请求的文件。 (请注意,我不能简单地redirect到所请求的文件 – 否则我会无尽的循环)

你总是可以有两个链接。 一个在浏览器中打开文档,另一个下载(使用不正确的内容types)。 这是Gmail所做的。

对于仍然在看这个的人来说,我使用了这里find的解决scheme,而且效果非常好。 谢谢Fabrizio!

我解决这个问题(用PHP)的方式如下:

假设你的URL是SomeScript.php?id=ID&data=DATA ,你要使用的文件是TEST.pdf

将URL改为SomeScript.php/id/ID/data/DATA/EXT/TEST.pdf

重要的是最后一个参数是您要Adobe使用的文件名(“EXT”可以是任何东西)。 确保在上面的string中没有特殊字符,顺便说一句。

现在,在SomeScript.php的顶部,添加:

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

然后将此函数添加到SomeScript.php (或您的函数库):

 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 

现在, $_REQUEST (或$_GET如果您愿意的话)像正常的$_REQUEST['id']$_REQUEST['data']等一样被访问

并且,Adobe将使用所需的文件名作为内联发送时的默认保存或电子邮件信息。

我在这里redirect,因为我有同样的问题。 我也尝试了特洛伊·霍华德的解决方法,但它似乎并没有工作。

我在这里做的方法是不再使用响应对象来即时写文件。 由于PDF已经存在于服务器上,我所做的是redirect我的页面指向该PDF文件。 很好用。

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

我希望我的模糊的解释给你一个想法。

试试这个,如果你的可执行文件是“get.cgi”

HTTP://server,org/get.cgi/filename.pdf文件= filename.pdf

是的,这完全是疯了。 在服务器上没有名为“filename.pdf”的文件,在可执行文件get.cgi下面都有目录。

但它似乎工作。 服务器忽略filename.pdf,pdf阅读器忽略“get.cgi”