强制缓存处理程序输出,主动抵制缓存

强制缓存处理程序输出,主动抵制缓存

我正在尝试强制缓存一段非常令人讨厌的 PHP 脚本,该脚本通过主动设置所有反缓存标头来主动尝试抵制缓存:

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Content-Type:  text/html; charset=UTF-8
Date:          Thu, 22 May 2014 08:43:53 GMT
Expires:       Thu, 19 Nov 1981 08:52:00 GMT
Last-Modified: 
Pragma:        no-cache
Set-Cookie:    ECSESSID=...; path=/
Vary:          User-Agent,Accept-Encoding
Server:        Apache/2.4.6 (Ubuntu)
X-Powered-By:  PHP/5.5.3-1ubuntu2.3

如果可以避免,我根本不想修改这段第三方代码,而只是让 Apache 缓存页面一段时间。我只会选择性地对特定页面执行此操作,这些页面对会话 cookie 等没有实际影响,即不包含任何个性化信息。

CacheDefaultExpire      600
CacheMinExpire          600
CacheMaxExpire          1800
CacheHeader             On
CacheDetailHeader       On
CacheIgnoreHeaders      Set-Cookie
CacheIgnoreCacheControl On
CacheIgnoreNoLastMod    On
CacheStoreExpired       On
CacheStoreNoStore       On
CacheLock               On

CacheEnable disk /the/script.php

Apache 是缓存页面没问题:

[cache:debug] AH00698: cache: Key for entity /the/script.php?(null) is http://example.com:80/the/script.php?
[cache_disk:debug] AH00709: Recalled cached URL info header http://example.com:80/the/script.php?
[cache_disk:debug] AH00720: Recalled headers for URL http://example.com:80/the/script.php?
[cache:debug] AH00695: Cached response for /the/script.php isn't fresh. Adding conditional request headers.
[cache:debug] AH00750: Adding CACHE_SAVE filter for /the/script.php
[cache:debug] AH00751: Adding CACHE_REMOVE_URL filter for /the/script.php
[cache:debug] AH00769: cache: Caching url: /the/script.php
[cache:debug] AH00770: cache: Removing CACHE_REMOVE_URL filter.
[cache_disk:debug] AH00737: commit_entity: Headers and body for URL http://example.com:80/the/script.php? cached.

然而,它总是坚持“缓存的响应不新鲜”,并且从不提供缓存的版本。我猜测这与标头有关Expires,标头将文档标记为已过期(但我不知道这是否是正确的假设)。我尝试使用 mod_headers 覆盖和取消设置标头,但这没有帮助;无论我尝试哪种组合,缓存都没有留下任何印象。我猜操作顺序是错误的,并且标头正在被重写缓存可以看到它们。early标头处理也无济于事。我尝试过CacheQuickHandler Off并尝试设置显式过滤器链,但没有任何帮助。但我真的只是在摸索,因为我没有太多配置 Apache 过滤器链的经验。

对于如何缓存这段令人讨厌的代码,有没有一个直接的解决方案?

答案1

空的 Last-Modified: 标头使请求无法缓存。因此,首先要做的是生成一个,一种解决方案是使用 php auto_prepend_file

创建一个文件prepend.php,内容如下:

  <?php header("上次修改时间:" . gmdate("D, d MYH:i:s"), " GMT"); ?>

然后在您的 vhost 配置中添加指令:php_value auto_prepend_file path_to_prepend.php

此时,您必须验证服务器响应是否具有正确的Last-Modified:标头。如果没有,我们将无法缓存它;如果是,那么您使用 mod_headers 和 mod_cache 的工作现在可能正在运行?

如果没有的话,你可以像这样使用 squid 和 apache:

Apache 配置

在正确的虚拟主机中,只需启用mod_rewrite并使用它重定向您想要缓存的流量:

<VirtualHost 你的当前虚拟主机:80>
 服务器名称 your.site.com
 ..
 RewriteEngine 开启

 # 这使得缓存服务器能够将请求视为 http://your.site.com/..
 ProxyPreserveHost 开启

 # 这应该在 VirtualHost 级别,而不是 <Directory> 或 .htaccess


 # DoSquid 环境变量决定我们是否将请求发送到缓存服务器
 # 根据您的需要进行调整
 RewriteRule /the/script.php - [E=DoSquid:Yes]

 # POST 不可缓存
 重写条件 %{REQUEST_METHOD} ^POST$
 重写规则 .* - [E:DoSquid:No]

 # 随意添加任何符合你需求的规则

 # 来自本地主机的请求是来自“主”虚拟主机的调用(见下文)
 RewriteCond %{REMOTE_ADDR} ^127\.0\.0\.1$ [E:DoSquid:No]

 RewriteCond %{ENV:DoSquid} ^Yes$
 重写规则 /the/script.php http://ip_of_caching_server/this/script.php [P,L,QSA]

 ..
 ..
<虚拟主机/>

# 您的缓存服务器将访问此 VirtualHost 作为您网站的主服务器
# 端口 8009 可以是任意端口,只要它必须是一个单独的虚拟主机

<VirtualHost 你的当前虚拟主机:8009>
 服务器名称 your.site.com
 ..
 RewriteEngine 开启

 # 这里大量使用 mod_headers 以获得可缓存的响应
 # 不用说,这可能会彻底破坏您的应用程序。响应如下
 # 完全匿名

 标头未设置 Set-Cookie
 标头未设置 Etag
 标头未设置 Pragma
 RequestHeader 未设置 Cookie

 # 现在修复 Cache-Control 标头..
 标头合并 Cache-Control public
 # max-age 很麻烦。如果未设置,则必须设置一个;如果为 0,则必须更改它
 标头合并缓存控制“max-age=bidon”
 # 当我们有以下情况时:Cache-Control max-age=.., ....
 标题编辑缓存控制“^(.*)max-age=(.*)max-age=bidon, (.*)$”$1max-age=$2$3
 # 当我们有以下情况时:Cache-Control yyy=bidon,max-age=..”
 标题编辑缓存控制“^(.*)max-age=(.*), max-age=bidon$”$1max-age=$2
 # 如果没有 max-age,则替换该值,设置为 10mn
 标题编辑缓存控制“max-age=bidon”“max-age=600”
 # 如果 max-age=0,则替换该值,设置为 10mn
 标题编辑缓存控制“max-age=0”“max-age=600”

 # 删除阻止缓存的 Cache-Control 参数
 标头编辑缓存控制“no-cache,” “”
 标头编辑缓存控制“no-store,” “”
 标头编辑 Cache-Control "post-check=0, " ""
 标头编辑 Cache-Control "pre-check=0, " ""
 标头编辑 Cache-Control“must-revalidate,” “”

 # 请求现在转发到第一个 vhost。它不会循环,因为我们不缓存来自 127.0.0.1 的请求
 ProxyPreserveHost 开启
 重写规则 ^(.*)$ http://127.0.0.1/$1 [P,L,QSA]

 ..
 ..
<虚拟主机/>

缓存服务器配置

您可能可以使用任何东西:squid,apache,varnish。使用 squid 您必须将其配置为反向代理并声明cache_peer your.site.com parent 8009 0 no-query originserver .. 也许您只需mod_cache在第二个 vhost 中启用即可实现您想要的。

相关内容