我已经为一个网站运行了一些测试,涉及动态内容(在这种情况下通过PHP/nginx(如何被各种浏览器缓存。
我得出的结论是,默认情况下,php 文件永远不会从缓存中提取,即使在移动浏览器中也是如此,即使在响应中没有Cache-Control
也没有Expires
参数,即使我不发送 POST 请求,我只是点击指向页面的链接。它们始终会重新下载。相比之下,css/js/image 文件是从缓存中获取的。
这对我有好处,因为我希望动态 html 总是命中后端,并以 Varnish 或我自己的 php/文件系统实现的形式具有缓存机制。
默认情况下,这通常是预期行为吗?顺便说一下,我正在使用会话饼干。
首先:我不是专家,你可以添加到这个主题中的东西很可能比我现在要做的更多,但它应该让你对它的工作原理有一个基本的了解。
CSS,图像和Javascript文件(通常(由Web服务器直接提供,而不会命中任何php脚本。因此,Web 服务器会处理这些文件的缓存本身。
对于 PHP 内容,Web 服务器调用您的 php 脚本并返回状态代码 200(如果没有错误或在脚本中没有以不同的方式明确指定(。
现在看到这个链接: 缓存教程
那里说:
如果响应中不存在验证器(ETag 或上次修改标头(,并且它没有任何明确的新鲜度信息,则它通常(但并非总是(被视为不可缓存。
也就是说,Web服务器不会将这些标头添加到php响应中。但它会将它们添加到静态资源中,如图像、css、js。
因此,对于将来对您的网站的请求,浏览器知道(由于这些标头(网站本身不可缓存,但图像是可缓存的。
如果您第二次请求网站,客户端通常会请求 php 脚本并再次获得正常响应,因为原始响应中不包含缓存信息(这里没有什么特别的(。
现在上面的文章说:
当缓存存储了包含上次修改标头的表示形式时,它可以使用它来询问服务器自上次看到表示形式以来是否发生了更改,并带有 If-Modified-Since 请求。
所以基本上浏览器会询问网络服务器图像是否更改,如果没有,服务器将返回"304 Not Modified"响应,而不会将实际图像添加到响应中(<= 这是缓存(。
正如我之前所说,如果未显式设置,php 脚本永远不会返回此状态代码。因此,在介绍了基础知识之后,我们可以进入重要的部分:;-(
dr 或 "如何缓存 PHP 页面">
您可能应该先阅读上面文章的"编写缓存感知脚本"部分。
但是,一种解决方案是:
- 在 php 脚本的响应中包含一些验证信息(例如"上次修改"标头((使用 header 函数(
- 在脚本开头检查"If-Modified-Since"标头,并返回状态代码"304 Not Modified"(如果适用((不运行脚本的其余部分(。
当重新请求之前返回的没有Expires
或Cache-Control
标头的资源时,浏览器应该始终再次查询服务器,无论内容类型是什么(毕竟,图像,CSS等也可以动态生成(。
唯一的区别是,真正的静态文件通常带有额外的Last-Modified
和/或Etag
响应标头,这允许浏览器缓存数据并使后续请求有条件(使用If-Modified-Since
和/或If-None-Match
请求标头(。如果内容是最新的,服务器将返回没有内容的响应304 Not Modified
浏览器将其从缓存中提取。动态脚本的输出不会发生这种情况(好吧,默认情况下不会发生(。