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
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
相关文章推荐
- apache中ob_start(\'ob_gzhandler\');前输出内容就会导致浏览出错:无效的或者不支持的压缩格式
- TFS - AT - Reporting配置 - 因为有正在运行的作业导致,"编辑"无法使用
- paping使用来测试联通&网站由于tcp协议导致的无法通信问题超时问题
- [转]PHP ob_start() and ob_start('ob_gzhandler')
- paping使用来测试联通&网站由于tcp协议导致的无法通信问题超时问题
- <div style="display:none">中更改的内容使用js无法获取
- 让文本框内容不可编辑,如果type="file",那么只能通过点击浏览来改变,不能通过输入文字改变
- PHP Warning: ob_start() : output handler 'ob_gzhandler conflicts with 'zlib output compression'
- 人脸识别引擎SeetaFaceEngine中Identification模块使用的测试代码
- codeblock无法进行调试,没有符号表被读取。请使用 "file" 命令。
- 测试的时候浏览出现 "WebDev.WebServer.exe 遇到问题需要关闭。我们对此引起的不便表示抱歉。
- 通过测试和代码告诉你Maven是如何使用mirror和repository的
- 在运行程序时报错:"如果在 Code First 模式下使用,则使用 T4 模板为 Database First 和 Model First 开发生成的代码可能无法 正常运行。若要继续使用 Database First 或 Model First,请确保在执行应用程序的 config 文件中指 定 Entity Framework 连接字符串。若要将这些从 Database First 或 Mod
- mini6410基于linux2.6.36内核通过NFS启动根文件系统总结(五内核测试 二 VFS: Cannot open root device "ubi0:FriendlyARM-root" )
- ASP.NET2.0中"无法显示 XML 页。 使用 XSL 样式表无法查看 XML 输入。"问题的解决
- 【iOS开发必收藏】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!【2012-12-11日更新获取"产品付费数量等于0的问题"】
- 解决"无法找到脚本库 "/aspnet_client/system_web/1_1_4322/WebUIValidation.js'.请尝到试手动放置此文件,或通过运行"aspnet_regiis -c"重新安装。"?
- 通过代码学习C#&.NET——委托使用(通用类设计)
- 使用批处理实现启动和停止服务的代码分析(net start&net stop)
- 解决JSP页面无法使用EasyUI里面class="easyui-dialog"的问题