使用正确的文件名在浏览器中安全地下载文件

问题描述:

我在一个网站上做了一些工作,该网站有一个安全的区域,只有在用户登录后才可以使用。在这个区域有一个链接到pdf文档的页面,可以下载。物理文档不在网站的根目录中。在PDF文档中的链接是这个样子:使用正确的文件名在浏览器中安全地下载文件

index.php页面=安全区域/下载文件& = protected.pdf

它执行以下(注:我知道这是必经之路强制下载,而不是打开文件浏览器):

// check security, get filename from request, prefix document download directory and check for file existance then... 

header('Content-Type: application/pdf'); 
header('Content-Disposition: attachment; filename="' . basename($file) . '"'); 
header('Content-Transfer-Encoding: binary'); 
header('Content-Length: ' . filesize($file)); 
header('Connection: Close'); 
set_time_limit(0); 
readfile($file); 

这种运作良好,但在Firefox 3和Internet Explorer 7(我还没有与其他任何浏览器进行测试)将不能打开此文件在浏览器内部,它们都显示下载对话框(如预期的那样)。如果选择“打开”而不是“保存”,则会下载文档,并在浏览器之外启动Adobe Reader以呈现文档。

我遇到的问题是在浏览器中下载文件,并保存了正确的默认文件名。

我想要在浏览器中打开文档。这样做的一种方法是使用标题“Content-Disposition:inline;”但这意味着我无法指定文件名(因为浏览器似乎被忽略)。有这样做的问题是,当我保存文档,默认名是该URL,而不是PDF文档的文件名:

http___example.com_index.php_page=secure_area_download&file=protected.pdf 

我怎样才能得到Firefox和Internet Explorer打开里面的文件浏览器并提供正确的默认文件名以保存?

我终于想出了解决这个问题的方法。

虽然RFC 2183显示文件名参数可以用于Content-Disposition标头字段的附件和内联,但似乎浏览器在使用内联时忽略文件名参数,而是尝试计算出文件名应该基于URL。如果URL没有查询字符串,那么跟在last /后面的URL部分似乎被用作文件名。

我已经更改了下载受保护PDF文档的链接,以使用不包含查询字符串的好网址,并使用带有.htaccess文件的mod_rewrite将这些好网址转换为使用正确参数执行正确脚本:

旧链接:

index.php?page=secure-area/download&file=document.pdf 

新建链接:

file/secure-area/download/document.pdf 

。htaccess的:

RewriteEngine On 
RewriteRule ^file/secure-area/download/(.*)$ index.php?page=secure-area/download&file=$1 [L] 

用于实际发送文件的脚本是为我所用之前(注意这个问题的例子同样使用内容处置:附件而不是内容处置:内联展示浏览器保存文档使用正确的文件名时,不是内联)。

// check security, get filename from request, prefix document download directory and check for file existance then... 
header('Content-Type: application/pdf'); 
header('Content-Disposition: inline; filename="' . basename($file) . '"'); 
header('Content-Transfer-Encoding: binary'); 
header('Content-Length: ' . filesize($file)); 
header('Connection: Close'); 
set_time_limit(0); 
readfile($file); 

现在PDF文档的浏览器中打开并保存时默认的文件名是

document.pdf 

,而不是

http___example.com_index.php_page=secure_area_download&file=document.pdf 

IE 7中的文件名转换空格+的和单独引号到%27的时候保存(Firefox不),我想停止发生,但同时我很满意我得到的。

+0

我非常想要投下这个票,因为它没有回答这个问题,但可能没有令人满意的答案。 – mjaggard 2012-12-04 10:25:57

+0

@mjaggard其实它回答我的问题。 – 2013-01-30 10:21:24

使用

Content-Disposition: inline; 
+0

这并不能解决我遇到的问题。我知道如何让文档在浏览器中打开。当在浏览器中打开文件时,我不知道如何为文件指定文件名,这就是这个问题的含义。 – 2008-12-19 21:29:22

你告诉它这样做,尝试使用内容处置:附件。尝试使用内容处置:内联。

+0

这并不能解决我遇到的问题。我知道如何让文档在浏览器中打开。当在浏览器中打开文件时,我不知道如何为文件指定文件名,这就是这个问题的含义。 – 2008-12-19 21:30:18

不,她在说的是使用'Content-disposition:inline'时无法指定文件名。 'Filename'只在使用'Content-disposition:attachment'时使用,如她的第一个例子。这会导致正在使用正确的文件名下载文档。然而,这个解决方案试图实现的是一个呈现INLINE的文档,当从浏览器下载时使用正确的文件名,而不是脚本名称。

当使用'inline'而不是url重写时,是否有任何其他方式指定文件名?我编写的用于呈现文档的页面需要数据库ID,因此我认为重写会更困难(文件名必须从数据库中查询)。

Content-disposition:inline可与文件名一起使用。但只有一些浏览器承诺并遵循这一点。只有当您自己保存文件名时才会看到效果,您将使用您使用内容处置定义的文件名。