7

我在 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
4

2 回答 2

12

传递静态文件时,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

编辑2

围绕配置包装 filesMatch 以仅禁用特定文件扩展名的缓存

<filesMatch ".(php|js|css)$">
    FileETag None
    [..]
</filesMatch>
于 2012-12-23T20:47:58.830 回答
2

如果我正确理解您的要求,您希望 Web 浏览器不记得您正在访问的网页的任何内容,并且您的 apache Web 服务器应该将其视为新页面请求。您可能首先要启用 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运行这个请求

于 2012-12-21T06:37:27.103 回答