使用正确的文件名在浏览器中安全下载文件 [英] Securly download file inside browser with correct filename

查看:24
本文介绍了使用正确的文件名在浏览器中安全下载文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在一个网站上做一些工作,该网站有一个安全区域,用户只有在登录后才能使用该区域.在该区域有一个页面,其中包含可下载的 pdf 文档链接.物理文档位于网站的根目录之外.pdf 文档的链接如下所示:

I am doing some work on a web site that has a secure area which is available to users only after they have logged in. In this area there is a page with links to pdf documents which can be downloaded. The physical documents are outside of the web site's root directory. The links to the pdf documents look something like this:

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

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

执行以下操作(注意:我知道这是强制下载而不是在浏览器打开文件的方法):

Which executes the following (note: I know this is the way to force a download rather than open the file inside the browser):

// 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(我没有用任何其他浏览器测试过)不会在浏览器中打开这个文件,它们都显示下载对话框(如预期).如果我选择打开而不是保存,则会下载文档并在浏览器外启动 Adob​​e Reader 以呈现文档.

This works well but in Firefox 3 and Internet Explorer 7 (I haven't tested with any other browser) won't open this file inside the browser, they both show the download dialog box (as expected). If I select Open rather than Save, the document is downloaded and Adobe Reader is started outside of the browser to render the document.

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

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

I would like the document to open in the browser. One way of doing this is using the header "Content-Disposition: inline;" but this means that I can't specify a filename (because is seems to be ignored by the browser). The problem with doing that is when I save the document, the default name is that of the URL, not the filename of the pdf document:

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

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

How can I get Firefox and Internet Explorer to open the document inside the browser and provide the correct default filename to save?

推荐答案

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

I've finally come up with a work around for this problem.

尽管 RFC 2183 表明文件名参数可用于 Content-Disposition 标头字段的附件和内联,但似乎浏览器在使用内联时忽略了文件名参数,而是尝试计算出文件名应该是什么以 URL 为基础.如果 URL 没有查询字符串,则 URL 中最后一个/之后的部分似乎用作文件名.

Although the RFC 2183 shows that a filename parameter can be used for both attachment and inline for the Content-Disposition header field, it seems that browsers ignore the filename parameter when inline is used but rather try to work out what the filename should be based on the URL. If the URL has no query string then the part of the URL that follows the last / seems to be used as the filename.

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

I have changed the links that download the protected PDF documents to use nice URLs that don't contain a query string and use mod_rewrite with a .htaccess file to convert those nice URLs to execute the correct script with the correct parameters:

旧链接:

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 来演示浏览器在 <强> 不 内联).

The script used to actually send the file is the same as I used before (note the example in the question uses Content-Disposition: attachment rather then Content-Disposition: inline to demonstrate browsers saving the document with the correct filename when not 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 文档在浏览器中打开,保存时默认文件名是

Now the PDF document opens inside the browser and when saved the default filename is

document.pdf

而不是

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

IE 7 在保存时将文件名中的空格转换为 + 并将单引号转换为 %27(Firefox 不会),我想阻止这种情况发生,但与此同时,我对我所做的感到满意得到了.

IE 7 converts spaces in the filename to +'s and single quotes to %27's when saved (Firefox doesn't), I would like to stop that from happening but for the meantime I'm happy with what I've got.

这篇关于使用正确的文件名在浏览器中安全下载文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆