6

我正在将文件名传递给下载页面。
即 somefile.xls

下载页面将完整目录路径添加回文件名。
即 c:\temp\somefile.xls

问题是现在设置标题的“Content-Disposition”不起作用。它要下载的文件名是完整的目录文件名路径。 即 c_temp_somefile

Content-Disposition 可以处理完整路径吗?

如果可以,我如何让我的脚本正确下载文件?

代码是:

$myad = $_GET['myad'];
$glob_string =  realpath('/foldera/folderb/folderc'). DIRECTORY_SEPARATOR .$myad;

header('Content-Type: application/excel');
$headerstring = 'Content-Disposition: attachment; filename='.$glob_string;
header($headerstring);
readfile($myad);

更新代码(来自答案):

$myad = $_GET['myad'];
$glob_string =  realpath('/mit/mit_tm/mrl_bol'). DIRECTORY_SEPARATOR .$myad;

header('Content-Type: application/excel');
$headerstring = 'Content-Disposition: attachment; filename='.$myad;
header($headerstring);
readfile($glob_string);    
4

4 回答 4

10

不要通过标头字符串传递完整路径,而是使用基本名称 ( $myad)。

您确实应该使用更好的验证$_GET['myad'],因为您的脚本会将任意路径传递给用户(readfile()获取未过滤的用户输入)。这是一个安全漏洞!

使用 计算真实路径realpath,确保文件在允许的文件夹内,然后basename()在完整路径上使用以获取纯文件名。通过Content-Disposition标头传递此子字符串,但使用readfile().


更新:您更新的代码仍然包含一个安全漏洞。如果$_GET['myad']包含../../../some/full/path,您的脚本会很乐意将任何请求的可读文件发送给客户端。

您应该使用以下代码段的内容:

$myad = $_GET['myad'];

$rootDir = realpath('/mit/mit_tm/mrl_bol');
$fullPath = realpath($rootDir . '/' . $myad);

// Note that, on UNIX systems, realpath() will return false if a path
// does not exist, but an absolute non-existing path on Windows.
if ($fullPath && is_readable($fullPath) && dirname($fullPath) === $rootDir) {
    // OK, the requested file exists and is in the allowed root directory.
    header('Content-Type: application/excel');
    // basename() returns just the file name.
    header('Content-Disposition: attachment; filename=' . basename($fullPath));
    readfile($fullPath);
}
于 2009-11-18T17:10:14.787 回答
9

您几乎可以将所需的所有内容放在Content-Disposition标题中,但出于安全原因,大多数浏览器会忽略或替换路径,并将它们转换为运行它们的操作系统的有效文件名。

Content-Disposition只是对浏览器的提示,Web 客户端并不强制遵守此设置。

所以,不,您不能强制下载到客户端计算机上的特定目录。

于 2009-11-18T17:10:29.527 回答
3

永远不能。如果浏览器接受完整路径,那么是时候快速提交错误了:这将是一个主要的安全漏洞。

于 2009-11-18T17:09:56.097 回答
0

我不知道这是否会有所帮助,但我认为 excel 文档的内容类型标题可能并不正确,我自己没有尝试过,但是那些微软包都是满口的,就像 mirosoft word 是
application/vnd.openxmlformats-officedocument.wordprocessingml.document

于 2013-04-14T22:22:41.913 回答