【发布时间】:2011-03-15 23:43:14
【问题描述】:
为了减少 http 请求,并使 js/css 文件的推出过程更容易,我设置了我的 php 应用程序来连接 js 和 css 文件。所有包含的文件按顺序组合成一个大文件,每个文件使用 2 个字母代码(例如 home.js 代码 =“AA”)。为了生成名称,我按照加载顺序将所有代码组合在一起,添加下划线,然后添加时间戳(例如“AABACE_12345678.js”)。然后在他们提供服务的目录中,我在 htaccess 中使用 apache 指令来解析带有 php(sing sethandler)的文件,这样我就可以控制标题,并在未更改的情况下返回 301 标题。
不幸的是,这不起作用...我已经用 firebug 的 Net 面板和 liveHTTPHeaders 测试了它的废话。页面每次都在加载文件,即使它应该在缓存中。以下是其中一个文件返回的响应标头示例:
Date Wed, 14 Jul 2010 17:00:28 GMT
Cache-Control private
Content-Encoding gzip
Etag "4b4a6d50f9acf924b9dce14e415f5c78"
Expires Wed, 28 Jul 2010 17:00:28 GMT
Vary Accept-Encoding
X-Powered-By PHP/5.2.6
Last-Modified Wed, 14 Jul 2010 16:59:35 GMT
Content-Length 39305
Content-Type text/css
注意:我省略了一些与缓存无关的标头,例如 keepAlive、服务器等
我还应该注意,我有条件地压缩内容,因此是私有缓存控制标头。我在这里想念什么?由于 expires 标头,内容应该被缓存。我正在从文件名+时间戳的 md5 生成 etag,因此永远不会更改文件。 Last-Modified 永远不会改变,Expires 永远不会改变......
[编辑]
所以经过进一步测试,我的 css 文件被缓存了,但我的 javascript 没有。如果我有两个文件,具有相同的缓存标头(etag、expires、last-modified、cache-control),但唯一不同的是内容类型(一个“text/css”一个“text/javascript”),只有 css正在被缓存......令人沮丧
【问题讨论】:
-
我假设时间戳是指最后一个 filemtime() 时间戳,而不是当前时间戳?
-
@Wrikken - 正确。每次更新包含的 js/css 文件之一时,它都会创建一个新文件,其中包含当前时间戳作为名称的一部分。但是用于生成 Etag/Last-modified 标头的时间戳等同于 filetime() 返回的时间戳。
-
好的,但是要特别确定:所需文件的时间戳保持不变,并且在指示要加载的文件时以某种方式自动记住时间戳?如果是这样,你有一个网址供我们测试吗?你不会是第一个被浏览器中“我正在开发这个网站,所以不要缓存任何东西”的个人设置所挫败的人。
-
@Wrikken - 是的,时间戳是相同的,它存储在文件中写入的变量中(PHP 在服务时解析它们,以生成标题)。我试过在多台机器上检查许多浏览器的标题,但都无济于事。所有缓存标头在文件的整个生命周期内都保持完全相同,因为当连接文件中包含的任何 js/css 文件的修改时间发生更改时,会生成一个全新的连接文件,应用程序使用不同的名称。旧文件不再使用,并由 cron 作业清理。