首页 文章

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

提问于
浏览
4

我正在一个网站上做一些工作,该网站有一个安全区域,只有在用户登录后才能使用 . 在这个区域有一个页面,其中包含可以下载的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以呈现文档 .

The problem I have is downloading the file inside the browser and having the correct default file name if saved.

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

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

如何让Firefox和Internet Explorer在浏览器中打开文档并提供正确的默认文件名来保存?

5 回答

  • 0

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

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

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

    旧链接:

    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来演示浏览器在 not 内联时使用正确的文件名保存文档) .

    // 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在保存文件时将文件名中的空格转换为's和单引号为%27'(Firefox没有),我想阻止这种情况发生,但与此同时我对我所拥有的内容感到满意 .

  • 0

    尝试使用

    Content-Disposition: inline;
    
  • 6

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

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

  • 1

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

  • -1

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

相关问题