如何控制 WebKit 中的 Google App Engine 缓存行为(etag 疯了)?
情况:运行 Google App Engine 网站,并将静态内容的 default_expiration 设置为“14d”
问题:在 Chrome 和 Safari 中访问网址(不 重新加载,只需将光标放在地址栏中并按 Enter 键),就会导致使用 If-None-Match 标头触发大量请求。正如预期的那样,响应始终为 304 Not Modified。我可以看到这些请求在 Charles 或 Fiddler 等调试代理中被触发。
想要:完全避免静态内容的这些请求和 304 响应 - 只需信任浏览器的缓存内容(当其可用时)。
我们使用标准的“缓存静态内容很长一段时间,当我们需要破坏缓存时,我们将负责将 ?version={version} 修改附加到我们的查询字符串”系统,所以我们真的想避免304的。
信念:我认为这是由应用程序引擎随每个静态内容响应发送的 etag 标头引起的。应用引擎 SDK 不会发送此标头,并且在使用 SDK 时我没有看到此 304 行为。
有什么建议吗?您可以关闭应用程序引擎静态内容的 etag 吗?
更新了静态内容示例: http:// /www.khanacademy.org/stylesheets/shared-package/compressed.css
Situation: running a Google App Engine site with my static content's default_expiration set to "14d"
Problem: in Chrome and Safari, visiting a URL (not reloading, just putting the cursor in the address bar and hitting Enter), causes a ton of requests to be fired with If-None-Match headers. The responses are always 304 Not Modified, as expected. I can watch these requests get fired in a debugging proxy like Charles or Fiddler.
Want: to avoid these requests and 304 responses entirely for static content -- simply trust the browser's cached content when it's available.
We use the standard "cache static content for a really long time, we'll take care of appending ?version={version} modifications to our query strings when we need to bust the cache" system, so we'd really like to avoid the 304's.
Belief: I think this is caused by the etag header that app engine sends down with every static content response. The app engine SDK does not send this header down, and I don't see this 304 behavior when messing around with the SDK.
Any advice? Can you turn off etags for app engine's static content?
Updated with an example piece of static content: http://www.khanacademy.org/stylesheets/shared-package/compressed.css
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
虽然我不相信有任何方法可以控制 GAE 的 etags 标头行为,但这是由 WebKit 中的一个错误引起的,该错误会导致在 POST 请求后收到 302 重定向时重新下载所有静态内容< /强>。
一旦 WebKit 修复了这个错误,问题就会消失。
如果必须,您可以通过刷新标头进行重定向而不是使用 302 重定向来临时解决此特定的 POST 后重定向错误。
https://bugs.webkit.org/show_bug.cgi?id=38690
Post/Redirect/Get 上的 WebKit 图像重新加载
http://www.google.com/support/forum/ p/Chrome/thread?tid=72bf3773f7e66d68&hl=en
While I don't believe there is any way to control the etags header behavior for GAE, this is caused by a bug in WebKit that causes all static content to be re-downloaded when receiving a 302 redirect after a POST request.
Once WebKit fixes this bug, the issue should go away.
If you must, you can temporarily work around this specific redirect-after-POST bug by redirecting via a Refresh header instead of using a 302 redirect.
https://bugs.webkit.org/show_bug.cgi?id=38690
WebKit image reload on Post/Redirect/Get
http://www.google.com/support/forum/p/Chrome/thread?tid=72bf3773f7e66d68&hl=en
您需要删除 Last-Modified 和 ETag 标头。
通过删除 ETag 标头,您将禁用缓存和浏览器验证文件的能力,因此它们被迫依赖您的 Cache-Control 和 Expires 标头。
实体标签 (ETag) 是一种检查缓存文件较新版本的机制。
删除 Last-Modified 和 ETag 标头,您将完全消除 If-Modified-Since 和 If-None-Match 请求及其 304 Not Modified 响应,因此文件将保持缓存状态而不检查更新,直到 Expires 标头指示新内容可用。
更多信息请参见:http://www.samaxes.com/2008/04/htaccess-gzip-and-cache-your-site-for-faster-loading-and-bandwidth- saving/。
不幸的是,我不知道如何针对 GAE 的静态内容关闭它们。
You need to remove both the Last-Modified and ETag headers.
By removing the ETag header, you disable caches and browsers from being able to validate files, so they are forced to rely on your Cache-Control and Expires header.
Entity tags (ETags) are a mechanism to check for a newer version of a cached file.
Removing both the Last-Modified and ETag header, you will totally eliminate If-Modified-Since and If-None-Match requests and their 304 Not Modified responses, so a file will stay cached without checking for updates until the Expires header indicates new content is available.
More info here: http://www.samaxes.com/2008/04/htaccess-gzip-and-cache-your-site-for-faster-loading-and-bandwidth-saving/.
Unfortunately I don't know how you can turn them off for GAE's static content.
Chrome 9.0、Windows。加载主页时,default.css 以及所有其他 .css 文件均从缓存中提供,无需发出请求。我认为这是特定于浏览器的行为,您还需要检查其他浏览器。
另外,检查这个谷歌说明,他们在调整缓存参数时帮助了我很多:
http://code.google.com/speed/page-speed/docs /缓存.html
Chrome 9.0, Windows. When loading your home page, default.css, as well as all other .css files are served from cache, without making a request. I think this is a browser-specific behavior, you need to check other browsers as well.
Also, check this Google instructions, they helped me a lot when tuning caching params:
http://code.google.com/speed/page-speed/docs/caching.html
由于这是 Chrome 和 Safari 的问题,您可以使用 HTML5 应用程序缓存 来防止服务器完全调用静态资源。请查看此处的示例。
Since this is an issue with Chrome and Safari, you could use HTML5 App Cache to prevent server calls on static resources completely. Check out an example here.
您的 ETag 值没问题。 ETag 不会强制重新验证。它只是使其比上次修改日期更可靠。我刚刚使用 Chrome 9 浏览到您的静态内容示例,您的内容已被缓存,并且不会进行不必要的重新验证。
您看到的问题可能与“始终重新验证”浏览器设置有关,这不是大多数浏览器的默认设置。它也可能是与 Mac webkit 相关的错误。
Your ETag value is fine. ETag does not force revalidation. It just enables it to be more reliable then last modification date. I just browsed to your static content example using Chrome 9, and your content is cached and not unnecessarily revalidated.
The problem you saw could be related to "always re-validate" browser settings, which are not the default for most browsers. It could also be a Mac webkit related bug.
尝试看看当您不按“输入”或刷新而只是点击链接时是否会发生同样的情况。在这种情况下,您的浏览器会执行不同的操作。特别是,如果您不使用刷新或再次显式请求页面,Safari 只会按照应有的方式执行请求。
您可以在 Mac 上非常简单地尝试一下。在某个端口上使用 netcat (nc) 运行一个简单的服务器,假设是 9090:
创建一个简单的页面,其中包含 http://localhost 的链接: 9090,单击它,然后观察 nc 命令显示的标题。
通过将响应键入 nc 来手动返回响应,例如,
再次单击链接并查看请求中的 If-None-Match 标头。在地址栏中的地址后按回车键,您会看到 Safari 不发送标头。
Try to see whether the same thing happens when you don't hit "enter" or refresh, but simply follow a link. Your browser does something different in those case. Safari particularly only does the requests the way they're supposed to be done if you don't use refresh or explicitly request the page again.
You can try this out very simply on a Mac. Run a simple server with netcat (nc) on some port, let's say 9090:
Create a simple page with a link to http://localhost:9090 in it, click it, and watch the headers your nc command displays.
Manually return a response by typing it into nc, e.g. something like
Click the link again and see the If-None-Match header in the request. Do a return after the address in the address bar, and you'll see Safari doesn't send the header.
我发布了一个新问题,通过 appengine-web.xml 配置请求此功能。
请检查并投票!
https://code.google.com/p/googleappengine/issues/detail?id=10339&sort=-id&colspec=ID%20Type%20Component%20Status%20Stars%20Summary %20语言%20优先级%20所有者%20日志
I posted a new issue to request this feature by appengine-web.xml configuration.
Please check and vote for it!
https://code.google.com/p/googleappengine/issues/detail?id=10339&sort=-id&colspec=ID%20Type%20Component%20Status%20Stars%20Summary%20Language%20Priority%20Owner%20Log