Apache-2.4.7忽略了响应头Content-Encoding:身份,而不是由PHP设置的Content-Encoding:none

我刚刚意识到我的明显问题(以及我在前面提到的问题中提到的StackOverflow问题中的“解决scheme” Content-Encoding: none )很可能只是由于误解实际上是如何工作的。 请在最后查看我的附录。


在我正在构build的PHP应用程序中,我试图pipe理自己的内容编码协商和压缩。

当我将响应头Content-Encoding从PHP内部设置为gzipdeflate ,Apache尊重这一点。 但是,当我将其设置为identity Apache忽略这一点,并压缩响应。

它似乎只尊重非标准的Content-Encoding: none ,因为我在这个堆栈溢出问题的一些答案和他们的评论中发现。

因此,我现在把它设置为none ,从PHP内部,然后通过.htaccess更改标题:

 Header edit Content-Encoding ^none$ identity 

…但这真的感觉像一个丑陋的黑客。 我希望我不必这样做,以防万一我切换服务器,例如。

这是一个已知的问题和/或这种非标准的行为logging在某处? 我似乎无法find任何具体的文件。

我也search了Apache的bug追踪器 ,但只能find一个切线相关的bug报告 ,关于Apache不尊重Accept-Encoding头值。


附录

当我在.htaccess禁用Apache的mod_deflate时(还有其他选项可以做到这一点):

 SetEnv no-gzip 1 

…并在PHP中设置Content-Encoding: identity ,Apache保持这个标题和内容完好,就好了。

因此,这是我认为实际发生的事情:

这不是Content-Encoding: none官方的信号给Apache来禁止压缩( Content-Encoding: bogus ,例如,产生相同的结果),这将解释为什么我找不到任何文档。

相反,它只是一个不是RFC标准的值。 因此mod_deflate保持内容不变,假设它是一些不想要干扰的非标准编码。

所以,当我在PHP中设置Content-Encoding: identity ,mod_deflate可能认为这是一个有效的RFC标准,意味着内容还没有被压缩,而且由于启用了mod_deflate,所以继续压缩它。

此外,如果我将Content-Encoding设置为gzipdeflate ,例如,mod_deflate可能会将其完全保留,或尝试压缩,但压缩algorithm会识别内容已被压缩。

也许有人可以证实这是否是对实际发生的事情的正确解释?


所以,一个可能的解决scheme是要么禁用我的PHP应用程序pipe理的一些选定的文件/path的mod_deflate,要么如果我的内容已经以其他方式压缩了,甚至可以禁用mod_deflate /站点范围/服务器范围。

所以,我已经设法解决了我的问题,考虑到我在我的问题中提出的假设,这似乎是正确的。 但不是没有挣扎。

试图只为PHP生成的内容实现它,我遇到了一些其他问题,我将在这里描述:

我最初在我的.htaccess有以下重写规则:

 RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l RewriteRule ^.*$ - [NC,L] RewriteRule ^.*$ index.php [NC,L] 

使用RewriteRule标志,你应该能够设置环境variables 。 所以,我想我应该可以在最后一个RewriteRule上设置E=no-gzip:1标志,方法是:

 RewriteRule ^.*$ index.php [NC,E=no-gzip:1,L] 

尽pipe前面提到过

 SetEnv no-gzip 1 

工作得很好, RewriteRule标志只是不能赶上。 然后我研究了Stack Overflow的各种相关问题,比如这一个 。 但是他们没有提供满意的解决scheme。

然后我暂时用apache_setenv( 'no-gzip', 1 );来设置PHP中的环境variablesapache_setenv( 'no-gzip', 1 ); ,这是诀窍。 但是这只是不正确的,也让我想知道为什么该死的RewriteRule标志不能正常工作。

然后,我决定做一个var_dump( $_SERVER ) ,看是否设置了RewriteRule标志,只是面对一个我曾经忘记的旧克星 :

 array(39) { ["REDIRECT_no-gzip"]=> string(1) "1" ["REDIRECT_APP_ENV"]=> string(11) "development" /* etc. */ } 

这个该死的REDIRECT_在重写时会被添加到环境variables中。

我的印象是,我最后一个RewriteRule上的L标志应该是停止重写,但显然我错误地解释了这个规则,这是条件:

 RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l RewriteRule ^.*$ - [NC,L] 

由于RewriteRule ^.*$ index.php [NC,E=no-gzip:1,L]重写为index.php ,这是一个常规文件( -s ),上述条件和规则仍然引入。

现在我已经改变了这个规则

 RewriteRule !^index.php - [NC,L] 

一切都终于如愿工作!