您的位置:首页 > 编程语言

ob_start("ob_gzhandler")与ob_*配合使用时导致浏览无法识别内容/开启gzip时且测试通过的下载代码

2013-03-28 16:49 471 查看
<?php
error_reporting(E_ALL);
ob_start("ob_gzhandler");//只要使用了它,后面的某些ob操作将导致问题
echo "content";
ob_end_clean();
ob_start();
ob_clean();
echo "more content";

firefox 12运行这上面的代码直接显示:

您尝试查看的页面无法显示,因为它使用了无效的或者不支持的压缩格式。

opera却能正常显示.

使用linux wget却也是正常的

root:/var/log/apache2# wget http://cms.china.net/temp_test.php --2012-05-22 23:44:42-- http://cms.china.net/temp_test.php Resolving cms.chinahrd.net... 219.232.28.8
Connecting to cms.chinahrd.net|219.232.28.58|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 12 [text/html]
Saving to: `temp_test.php'

100%[===========================================================================>] 12 --.-K/s in 0s

2012-05-22 23:44:43 (2.40 MB/s) - `temp_test.php' saved [12/12]

root:/var/log/apache2# cat temp_test.php
more contentroot:/var/log/apache2#

所以这应该是浏览解析的问题.肯定也是gzip处理后的问题导致.
最好的方法是不使用gzip,或是使用了就不要使用ob其它操作.

用话,有人建议这样用

ob_start("ob_gzhandler");echo("trashed");ob_end_clean();ob_start("ob_gzhandler");echo("output");ob_end_flush();

-------------------------开启gzip功能且能正常下载的代码,一般需要测试的文件是rar之类严格内容格式的文件类型,测试时可以使用------

function phpDown($file, $name = null){
$file = str_replace(array('../', './'), '', $file);//不允许导致安全问题的路径出现,需要过滤./../

if( file_exists($file) ){
$path_parts = pathinfo($file);
$size = filesize($file);
if ($size < 1) exit('空白文件,不需要下载');
$fileName = 'filename'.(strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox')>0 ? "*=\"utf8''" : '="')
.rawurlencode($name ? $name.'.'.strtolower($path_parts["extension"]) : basename($file)).'"';//解决firfox与其它浏览处理中文名问题
if(ob_get_length() !== false) @ob_end_clean();//尝试清除影响内容的前面输出
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');//任何文件类型都保存,非浏览
header('Content-Disposition: attachment; ' .$fileName);
header('Content-Encoding: none');//如果使用gzip将会导致问题,必须强制下载不使用压缩
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . $size);//给出大小
readfile($file);
exit;
} else die('File Not Found');
}

-----------------查看下载页面返回的全部内容:header与body,利用它可以看到浏览器怎么处理-------

<?php
header('Content-Type: text/html; charset=UTF-8');
var_dump(htm('/index.php?m=chrd&c=tooldown&a=down&aid=16170'));
/*
* 从其它服务器请求htm,目的是方便修改,只需要修改一个htm多个页面变化
*/
function htm($file) {
$incHost = 'cms.china.net';
$htm = fsockopen($incHost, 80, $errno, $errstr, 30);

if (!$htm) {
return "$errno, $errstr";
} else {
$crlf = "\r\n";
$get = "GET {$file} HTTP/1.1{$crlf}"
."Host: {$incHost}{$crlf}"
."Connection: Close{$crlf}"
.$crlf;//表示提交结束了
fwrite($htm, $get);
$get = '';

while (!feof($htm)) {
$get .= fgets($htm, 128);
}

fclose($htm);

return $get;
}
}

-------
对于这个问题,网上很多人都只是说是php bug,经过测试应该不是,尝试了一天,误以为报头中编码这块只能设置编码,不能禁用.因为从浏览器中总是看到gzip,而使用上面的php查看返回头却是没有gzip报头的.导致rar格式有误的就是因为gzip报头影响只要处理掉它就基本上没事,这步是关键,对于清空缓存,这步,只是前面有输出时才是有必要的.那只是加了个保险

上面的问题在我测试时只出现在下面这个环境下
Apache Version Apache/2.2.20 (Win32) PHP/5.3.3

而我在这个环境测试没有任何上面提到的问题.

PHP Version 5.4.0
Windows NT QIDIZI 6.1 build 7601 (Windows 7 Home Basic Edition Service Pack 1) i586
Apache/2.2.17 (Win32) PHP/5.4.0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐