为什么我的JavaScript和CSS没有缓存?

11

似乎仅仅JavaScript和CSS没有被缓存,但是图片被缓存了。

我正在使用Firebug,在刷新页面时,我注意到Firebug中有很多200 HTTP响应的js/css,但是所有我的图片都收到了304 HTTP代码(内容未修改)。所以看起来我的JS和CSS没有被缓存。

此外,当使用YSlow帮助确定我的JS/CSS内容不被缓存的问题时,它告诉我:

有4个组件ETags配置错误

下面列出了我的.htaccess文件:

Options -Indexes
Options +FollowSymLinks  

# Enable ETag
FileETag MTime Size

# Set expiration header
ExpiresActive on
ExpiresDefault "access plus 1 week"

# Compress some text file types
AddOutputFilterByType DEFLATE text/html text/plain text/css text/xml application/x-javascript text/javascript application/javascript application/json

# Deactivate compression for buggy browsers
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

# Set header information for proxies
Header append Vary User-Agent

我 .htaccess 访问文件有什么问题,导致它无法缓存我的 CSS 或 JavaScript?


三个问号其实并不必要。 - stepancheg
3
好的,请提供需要翻译的内容。 - MrDoAlot
重复:https://dev59.com/O0fRa4cB1Zd3GeqP9oO3 - Gumbo
@gumbo - 我关闭了另一个话题。这个话题是现在的实时问题。 - MrDoAlot
6个回答

7
请考虑禁用ETag!
请考虑以下设置:
Header unset ETag
FileETag None
Header set Cache-Control "max-age=2678400"

第一条和第二条规则完全禁用了ETag, 所以浏览器有一定的强制执行Cache-Control标头。最后一条规则告诉浏览器缓存该文件2678400秒,即1个月。调整设置以适合自己的需求,并将此配置应用于包含静态文件的目录(例如,通过在该目录中放置一个.htaccess文件)。
如果您正在使用多个服务器来提供静态内容,并且/或者不确定这些服务器报告的最后修改时间,请考虑使用:
Header unset Last-Modified

这会告诉Apache不要提供任何Last-Modified标头,因此浏览器只能依据Cache-Control max-age标头监听缓存。

我在许多高流量网站上使用了这些设置,并且禁用ETag和Last-Modified标头确实帮助将流量减少到原来的五分之一。特别是Internet Explorer对这些设置非常敏感。

请注意:禁用Last-Modified将阻止浏览器请求304内容未修改的请求。根据我的经验,这是有益的,因为Web服务器需要处理更少的请求,浏览器更多地依赖您提供的Cache-Control设置。但这可能或可能不适合您。如果您提供“Last-Modified”标头,则某些浏览器每隔几分钟就会尝试验证资产,这就是我建议完全禁用其使用的原因。

哦,如果您不确定自己的缓存,请使用http://www.redbot.org/测试您的资产,它会快速告诉您浏览器对您的标头的含义以及如何解释您使用的不同缓存控制设置。


2

如果ETag不符合某种模式,YSlow将报告配置错误。由于您正在压缩CSS和JS,因此ETag的输出类似于以下内容:

Etag "1e10-4889909861a80"-gzip

看到末尾的-gzip了吗?这是由apache(仅适用于版本2)放置的。那就是导致“错误”的原因。YSlow希望看到类似这样的东西:

Etag "xxxx-xxxxxxxxxxxxx"

基本上,你不能修复它,因为它并没有损坏。所以如果你不知道该怎么做,就不要疯狂地试图获得完美的分数。即使雅虎首页也只得了90分。

嗯,Apache确实有问题;Etag无效。据我所知,这在Apache中已经修复了。 - Julian Reschke
难道不应该是 Etag "1e10-4889909861a80-gzip" 吗?看起来像是 Apache 的 bug。 - Tomáš Fejfar

2

这个YSlow错误信息非常误导人!

实际上,YSlow抱怨的是你使用了ETags!

YSlow运行在你的浏览器中--它无法知道ETags是否配置正确。作为一个经验法则,它表示你不应该使用ETags,因为在多服务器环境中,你更有可能将它们配置不正确而不是正确配置。(而YSlow面向的是拥有大型、多服务器网站的用户。)

当然,如果你只是单服务器设置,或者你在分布式服务器设置中知道自己在做什么,那么ETags就没问题。但是YSlow无法知道这一点。

在错误描述页面的评论中有很多关于此问题的讨论,你应该去看看:http://developer.yahoo.net/blog/archives/2007/07/high_performanc_11.html

我还在ServerFault上找到了这个答案,重申了这一点:https://serverfault.com/questions/55919/yslow-says-etags-are-misconfigured-how-to-configure-etags-properly-on-iis7


1

是的,这是正确和众所周知的行为(也许并不是真正需要的)。

阅读http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html关于ETag的内容。

可能你只想在服务器上禁用ETag。

编辑:此外,使用LiveHTTPHeaders插件来了解你的浏览器的操作。它比FireBug更适合这个任务。


所以我已经禁用了ETag支持,但似乎相同的图像/js/css并没有返回304代码。无论我启用还是禁用ETag都没有任何区别。 - MrDoAlot
经过进一步的审查,似乎只有JavaScript和CSS没有缓存...但是图像正在缓存。 - MrDoAlot
我在使用LiveHTTPHeaders插件时注意到了这一点,感谢stepancheg。有什么想法为什么CSS和JS没有被缓存? - MrDoAlot
1
第一次请求.js时,显示服务器发送的标头。 - stepancheg
@stepancheg - 你有什么想法,为什么我的JS和CSS文件没有被缓存? - MrDoAlot
@MrDoAlot 在你展示服务器发送的首个 .js 头部之前,我没有任何想法。 - stepancheg

1
我遇到了和你一样的问题。 移除ETag会起作用。
在配置文件中添加以下内容: FileETag none

0

嗨,我也遇到了同样的问题。 但是仅仅输入FileETag none并没有起作用。

我解决的方法(我不知道这是否正确 - 但它有效)是将

FileETag none

放在我的htaccess文件底部。

然后ySlow就很高兴了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接