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

时间:2008-12-19 19:07:16

标签: security file browser download inline

我正在一个网站上做一些工作,该网站有一个安全区域,只有在用户登录后才能使用。在这个区域有一个页面,其中包含可以下载的pdf文档的链接。物理文档位于Web站点的根目录之外。 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在浏览器中打开文档并提供正确的默认文件名进行保存?

5 个答案:

答案 0 :(得分:6)

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

尽管RFC 2183显示文件名参数可以用于Content-Disposition头字段的附件和内联,但是当使用内联时,浏览器似乎忽略了filename参数,而是尝试找出文件名应该是什么基于URL。如果URL没有查询字符串,则最后一个/后面的URL部分似乎用作文件名。

我已经更改了下载受保护的PDF文档的链接,以使用不包含查询字符串的漂亮URL,并使用带有.htaccess文件的mod_rewrite来转换这些不错的URL,以使用正确的参数执行正确的脚本: / p>

旧链接:

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]

用于实际发送文件的脚本与我之前使用的相同(请注意问题中的示例使用Content-Disposition:attachment而不是Content-Disposition:inline来演示浏览器在<时使用正确的文件名保存文档强>不内联)。

// 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没有),我想阻止这种情况发生但同时我对我的内容感到满意得到。

答案 1 :(得分:1)

尝试使用

Content-Disposition: inline;

答案 2 :(得分:0)

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

除了url重写之外,使用'inline'时还有其他指定文件名的方法吗?我为渲染文档编写的页面采用了数据库ID,因此我认为重写会更困难(必须从数据库中查询文件名)。

答案 3 :(得分:0)

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

答案 4 :(得分:-1)

你告诉它通过使用Content-disposition:attachment来做到这一点。尝试使用Content-disposition:inline。