【问题标题】:Apache serves old versions of filesApache 提供旧版本的文件
【发布时间】:2012-12-20 20:40:33
【问题描述】:

我在 localhost 上调试 js 代码,我需要防止浏览器缓存文件。我不能使用附加到 url 的时间戳,因为它会删除 chrome 调试器断点。

通常我不必刷新缓存,但过段时间每个人都会这样做。这是一个大问题,因为我去其他地方寻找错误。我前段时间将此代码添加到apache:

    <IfModule mod_headers.c>
            Header add Expires "Sun, 19 Nov 1978 05:00:00 GMT"
            Header add Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"
    </IfModule>

有人能解释一下为什么 Apache 会误认为一个文件是有效的,或者在配置代码中提供一些可以一劳永逸地解决这个问题的附加内容吗?

使用以下解决方案的标题:

<IfModule mod_expires.c>
  expiresActive On
  ExpiresDefault "access plus 1 seconds"
  ExpiresByType text/html "access plus 1 seconds"
  ExpiresByType text/javascript "access plus 1 seconds"
  ExpiresByType application/x-javascript "access plus 1 seconds"
</IfModule>

http://localhost/static/images/%d0%9a%d0%be%d0%bf%d0%b8%d1%8f%20logo_inner.png

GET /static/images/%d0%9a%d0%be%d0%bf%d0%b8%d1%8f%20logo_inner.png HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:16.0) Gecko/20100101 Firefox/16.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/static/images/
Cache-Control: max-age=0

HTTP/1.1 200 OK
Date: Sun, 23 Dec 2012 19:33:20 GMT
Server: Apache/2.2.22 (Ubuntu)
Last-Modified: Thu, 28 Jun 2012 17:32:51 GMT
Etag: "b3c27-f1f-4c38bb88d96c0"
Accept-Ranges: bytes
Content-Length: 3871
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Keep-Alive: timeout=15, max=99
Connection: Keep-Alive
Content-Type: image/png



HTTP/1.1 200 OK
Date: Sun, 23 Dec 2012 19:33:54 GMT
Server: Apache/2.2.22 (Ubuntu)
Last-Modified: Thu, 28 Jun 2012 17:32:51 GMT
Etag: "b3c27-f1f-4c38bb88d96c0"
Accept-Ranges: bytes
Content-Length: 3871
Cache-Control: max-age=1
Expires: Sun, 23 Dec 2012 19:33:55 GMT
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: image/png




The second request:

http://localhost/static/images/%d0%9a%d0%be%d0%bf%d0%b8%d1%8f%20logo_inner.png

GET /static/images/%d0%9a%d0%be%d0%bf%d0%b8%d1%8f%20logo_inner.png HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:16.0) Gecko/20100101 Firefox/16.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/static/images/
If-Modified-Since: Thu, 28 Jun 2012 17:32:51 GMT
If-None-Match: "b3c27-f1f-4c38bb88d96c0"
Cache-Control: max-age=0

HTTP/1.1 304 Not Modified
Date: Sun, 23 Dec 2012 19:34:58 GMT
Server: Apache/2.2.22 (Ubuntu)
Connection: Keep-Alive
Keep-Alive: timeout=15, max=99
Etag: "b3c27-f1f-4c38bb88d96c0"
Expires: Sun, 23 Dec 2012 19:34:59 GMT
Cache-Control: max-age=1

【问题讨论】:

标签: apache2 cache-control


【解决方案1】:

在交付静态文件时,Apache 会发送一个 ETag 标头,类似于文件的校验和。浏览器会缓存文件并记住 ETag,它会与下一个请求一起发送。

如果文件更改浏览器ETag 应该不同并且网络服务器应该重新发送,当etag 相等时,网络服务器将响应304 Not Modified。 ETag 机制的优先级高于其他缓存头。

要禁用 etags,您可以使用 apaches

FileETag None

http://httpd.apache.org/docs/current/en/mod/core.html#fileetag

维基百科有一篇关于 Etag 标头的好文章 http://en.wikipedia.org/wiki/HTTP_ETag

编辑

这应该是防水配置

FileETag None
<ifModule mod_headers.c>
    Header unset ETag
    Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>

不要忘记配置更改需要重新启动服务器才能生效。

sudo /etc/init.d/httpd restart

EDIT2

将 filesMatch 包裹在配置周围以仅禁用特定文件扩展名的缓存

<filesMatch ".(php|js|css)$">
    FileETag None
    [..]
</filesMatch>

【讨论】:

  • 谢谢,但它没有按您的预期工作(我仍然得到 304 标头)。我什至还尝试添加 Header unset Pragma Header unset ETag FileETag None
  • 删除浏览器缓存一次,确保 ETag 实际上不再由 apache 设置(正确配置)
  • ETag 肯定是由 Apache 发送的。我不知道如何更正配置,因为我将这些行添加到我的虚拟主机文件中,正如你所说的和其他教程所说的那样。
  • 在上面添加了一个配置示例,应该适用于所有情况
  • 成功了,谢谢。另外,有没有办法只为 .js、.css 和 .php 制作这个?
【解决方案2】:

如果我正确理解您的要求,您希望网络浏览器不记得您正在访问的网页的任何内容,并且您的 apache 网络服务器应该将其视为新页面请求。您可能首先要启用 mod_expires 和 mod_headers ,我使用 ubuntu 所以我的是

a2enmod headers && a2enmod expires && service apache2 restart

比你想添加下面的代码来做最小缓存控制,

<IfModule mod_expires.c>
  expiresActive On
  ExpiresDefault "access plus 1 seconds"
  ExpiresByType text/html "access plus 1 seconds"
  ExpiresByType text/javascript "access plus 1 seconds"
  ExpiresByType application/x-javascript "access plus 1 seconds"
</IfModule>

如果你使用的是 firefox,你可以通过安装/运行 Live Http header Plugin 来测试,或者如果你是 linux/unix,你可以使用 curl -v your_url

运行这个请求

【讨论】:

  • 我用 liveheaders 测试了这个并附加了调试输出。在第二次尝试时,文件从缓存中加载。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-18
  • 2019-10-31
  • 1970-01-01
  • 1970-01-01
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多