我正在构建这个php脚本,它显示给定文件夹的子文件夹和文件。文件应该下载。
为了尽可能少地披露信息,目录中的每个项目都是一个带有包含html标记的提交按钮的表单。 send方法是POST。
如果我点击某个目录,它会打开该目录并显示内容。 如果我点击一个文件,它会显示一个下载提示,文件下载就好了。 但是之后的点击,我看到了这样的事情:
0 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
trailer
<</Size 34>>
startxref
116
%%EOF
HTTP/1.1 200 OK
Date: Mon, 31 Aug 2009 21:01:36 GMT
Server: Apache
X-Powered-By: PHP/5.2.5
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Keep-Alive: timeout=15, max=93
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html
2822
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
列出了显示页面的其余html代码源。
这里发生了什么?
更新:我的“强制下载”代码:
function offerToDownloadFile($filename, $access_type='url') {
// converting url to local path so Apache can find the file.
// force download:
// required for IE, otherwise Content-disposition is ignored
if (ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
if($access_type === 'url') {
// access type is via the file 's url
$parsed_url = parse_url($filename);
$fileinfo = pathinfo($filename);
$parsed_url['extension'] = $fileinfo['extension'];
$parsed_url['filename'] = $fileinfo['basename'];
$parsed_url['localpath'] = LOCALROOT . $parsed_url['path'];
}
else {
// access type is the local file path
$fileinfo = pathinfo($filename);
$parsed_url['localpath'] = $filename;
$parsed_url['filename'] = basename($filename);
$parsed_url['extension'] = $fileinfo['extension'];
}
// just in case there is a double slash created when joining document_root and path
$parsed_url['localpath'] = preg_replace('/\/\//', '/', $parsed_url['localpath']);
if (!file_exists($parsed_url['localpath'])) {
die('File not found: ' . $parsed_url['localpath']);
}
$allowed_ext = array('ics','pdf', 'png', 'jpg', 'jpeg', 'zip', 'doc', 'xls', 'gif', 'exe', 'ppt');
if (!in_array($parsed_url['extension'], $allowed_ext)) {
die('This file type is forbidden.');
}
switch ($parsed_url['extension']) {
case "ics": $ctype="text/calendar";
break;
case "pdf": $ctype = "application/pdf";
break;
case "exe": $ctype = "application/octet-stream";
break;
case "zip": $ctype = "application/zip";
break;
case "doc": $ctype = "application/msword";
break;
case "xls": $ctype = "application/vnd.ms-excel";
break;
case "ppt": $ctype = "application/vnd.ms-powerpoint";
break;
case "gif": $ctype = "image/gif";
break;
case "png": $ctype = "image/png";
break;
case "jpeg":
case "jpg": $ctype = "image/jpg";
break;
default: $ctype = "application/force-download";
}
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false); // required for certain browsers
header("Content-Type: $ctype");
header("Content-Disposition: attachment; filename=\"" . $parsed_url['filename'] . "\";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($parsed_url['localpath']));
readfile($parsed_url['localpath']);
clearstatcache();
exit();
}
答案 0 :(得分:2)
从外观上看,你的文件下载脚本可能设置了错误的Content-Length,因此文件的最后几个字节可能会溢出到下一个请求中,导致所有破坏方式。
您使用的是哪种Web服务器和操作系统,以及如何调用PHP?因为如果它是Windows,我怀疑你的PHP安装可能以某种方式写入stdout作为文本而不是二进制流。这会导致每个\ n字节转换为\ r \ n序列,这可能会使大多数二进制文件不可读,并使响应主体比Content-Length标头所说的更长。
$ parsed_url ['localpath'] = LOCALROOT。 $ parsed_url [ '路径'];
这似乎很危险。我希望在尝试这样的事情之前,检查并验证$ filename的生命周期。 (文件名验证看起来很难。)
答案 1 :(得分:-1)
我无法告诉你所有的垃圾是什么,但为了避免它,在您发送文件后,请致电die()
。