我在将项目转移到新的生产服务器时遇到了问题。Apache mod_deflate 模块不会压缩 PHP 应用程序的 HTML 输出。其他资源(如样式表和 javascript 文件,甚至 html 页面)与 PHP 输出的内容类型 (text/html) 相同,但都被压缩了!
项目在 .htaccess 中使用以下规则(来自 HTML5 样板):
<IfModule mod_deflate.c> # 强制压缩损坏的标头 developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping/ <IfModule mod_setenvif.c> <IfModule mod_headers.c> SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding RequestHeader 附加 Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding </IfModule> </IfModule> # HTML、TXT、CSS、JavaScript、JSON、XML、HTC: <IfModule 过滤器模块> 过滤声明压缩 FilterProvider COMPRESS DEFLATE resp=Content-Type $text/html FilterProvider COMPRESS DEFLATE resp=Content-Type $text/css FilterProvider COMPRESS DEFLATE resp=Content-Type $text/plain FilterProvider COMPRESS DEFLATE resp=Content-Type $text/xml FilterProvider COMPRESS DEFLATE resp=Content-Type $text/x-component FilterProvider COMPRESS DEFLATE resp=Content-Type $application/javascript FilterProvider COMPRESS DEFLATE resp=Content-Type $application/json FilterProvider COMPRESS DEFLATE resp=Content-Type $application/xml FilterProvider COMPRESS DEFLATE resp=Content-Type $application/xhtml+xml FilterProvider COMPRESS DEFLATE resp=Content-Type $application/rss+xml FilterProvider COMPRESS DEFLATE resp=Content-Type $application/atom+xml FilterProvider COMPRESS DEFLATE resp=Content-Type $application/vnd.ms-fontobject FilterProvider COMPRESS DEFLATE resp=Content-Type $image/svg+xml FilterProvider COMPRESS DEFLATE resp=Content-Type $image/x-icon FilterProvider COMPRESS DEFLATE resp=Content-Type $application/x-font-ttf FilterProvider COMPRESS DEFLATE resp=Content-Type $font/opentype 过滤链压缩 FilterProtocol COMPRESS DEFLATE 更改=是;字节范围=否 </IfModule> </IfModule>
我们有一台运行相同 Apache、OS 和 PHP 版本的测试机器。在那台机器上,压缩对 PHP 输出工作正常。我检查并比较了 Apache 和 PHP 配置文件,据我所知,它们都是一样的。
我尝试了几种输出 PHP 内容的方式,使用输出缓冲或只是简单地回显内容。结果都一样,没有压缩。
PHP 输出的示例响应标头:
HTTP/1.1 200 正常 日期:2012 年 4 月 25 日星期三 23:30:59 GMT 服务器:Apache 接受范围:字节 到期时间:1981 年 11 月 19 日星期四 08:52:00 GMT 缓存控制:公共 指令:无缓存 变化:用户代理 保持活动:超时=5,最大值=98 连接:保持连接 传输编码:分块 内容类型:text/html;字符集=utf-8
css 文件上的响应头示例:
HTTP/1.1 200 正常 日期:2012 年 4 月 25 日星期三 23:30:59 GMT 服务器:Apache 最后修改时间:2011 年 7 月 4 日星期一 19:12:36 GMT 变化:接受编码、用户代理 内容编码:gzip 缓存控制:公共 到期时间:2012 年 5 月 25 日星期五 23:30:59 GMT 内容长度:714 保持活动:超时=5,最大值=100 连接:保持连接 内容类型:text/css;字符集=utf-8
有谁知道或者经历过同样的“问题”吗?
谢谢!
答案1
如果 Apache 无法判断返回的内容有多大,它将自动采用分块编码。根据您的 PHP 脚本的运行方式(CGI、FastCGI 等),Apache 在开始将内容返回给用户时可能不知道内容的大小。也就是说,如果您让它在整个脚本中输出内容,它可能会立即将该数据写入客户端的缓冲区。
它之所以能处理静态文件,是因为 Apache 在开始返回静态文件时就知道它们的大小。这可能表明您的 Apache/PHP 配置存在问题(即,它在脚本返回输出时开始写入),或者您的脚本本身的工作方式存在问题。
换句话说,这听起来像是 PHP 或 Apache/PHP 连接器的问题,而不是 的问题mod_deflate
。
答案2
请检查是否启用了 PHP 输出压缩。这可以在 php.ini 文件中或通过运行时指令完成。检查文档更多细节。