23

情况:运行一个 Google App Engine 网站,我的静态内容的 default_expiration 设置为“14d”

问题:在 Chrome 和 Safari 中,访问 URL(重新加载,只是将光标放在地址栏中并按 Enter 键)会导致使用 If-None-Match 标头触发大量请求。正如预期的那样,响应始终是 304 Not Modified。我可以看到这些请求在 Charles 或 Fiddler 等调试代理中被触发。

想要:完全避免针对静态内容的这些请求和 304 响应——只需信任浏览器的缓存内容(当它可用时)。

我们使用标准的“缓存静态内容很长时间,当我们需要破坏缓存时,我们会处理将 ?version={version} 修改附加到我们的查询字符串”系统,所以我们真的很想避免304 的。

信念:我认为这是由应用引擎随每个静态内容响应发送的 etag 标头引起的。应用程序引擎 SDK 不会向下发送此标头,并且在使用 SDK 时我看不到此 304 行为。

有什么建议吗?你能关闭应用引擎静态内容的 etags 吗?

更新了一个静态内容示例: http ://www.khanacademy.org/stylesheets/shared-package/compressed.css

4

7 回答 7

8

虽然我不相信有任何方法可以控制 GAE 的 etags 标头行为,但这是由 WebKit 中的一个错误引起的,该错误会导致在 POST 请求后收到 302 重定向时重新下载所有静态内容

一旦 WebKit 修复了这个 bug,这个问题就会消失。

如果必须,您可以通过 Refresh 标头重定向而不是使用 302 重定向来临时解决此特定的 redirect-after-POST 错误。

https://bugs.webkit.org/show_bug.cgi?id=38690

WebKit 图像在 Post/Redirect/Get 上重新加载

http://www.google.com/support/forum/p/Chrome/thread?tid=72bf3773f7e66d68&hl=en

于 2011-02-28T21:14:46.463 回答
5

您需要删除 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 的静态内容关闭它们。

于 2010-12-11T02:48:23.757 回答
3

铬 9.0,Windows。加载主页时,default.css 以及所有其他 .css 文件都是从缓存中提供的,无需发出请求。我认为这是特定于浏览器的行为,您还需要检查其他浏览器。

另外,请查看此 Google 说明,它们在调整缓存参数时帮助了我很多: http ://code.google.com/speed/page-speed/docs/caching.html

于 2010-12-10T19:46:56.220 回答
3

由于这是 Chrome 和 Safari 的问题,您可以使用HTML5 App Cache来完全防止服务器调用静态资源。在这里查看一个示例。

于 2010-12-10T20:10:45.650 回答
3

您的 ETag 值很好。ETag 不强制重新验证。它只是使它比上次修改日期更可靠。我刚刚使用 Chrome 9 浏览了您的静态内容示例,并且您的内容已被缓存并且没有不必要的重新验证。您看到的问题可能与“始终重新验证”浏览器设置有关,这不是大多数浏览器的默认设置。它也可能是与 Mac webkit 相关的错误。

于 2011-02-10T11:21:22.713 回答
2

尝试查看当您不点击“输入”或刷新时是否会发生同样的事情,而只需点击链接即可。在这种情况下,您的浏览器会做一些不同的事情。如果您不使用刷新或再次明确请求页面,Safari 尤其只会按照应有的方式执行请求。

您可以在 Mac 上非常简单地尝试一下。在某个端口上运行一个带有 netcat (nc) 的简单服务器,比如 9090:

nc -l 9090

创建一个简单的页面,其中包含指向http://localhost:9090的链接,单击它,然后查看 nc 命令显示的标题。

通过将响应键入 nc 来手动返回响应,例如类似

HTTP/1.0 200 OK
ETag: "xyz"
Content-type: text/plain

Some text.

再次单击该链接并查看请求中的 If-None-Match 标头。在地址栏中的地址后回车,您会看到 Safari 不发送标头。

于 2010-12-10T21:38:55.533 回答
-1

我发布了一个新问题以通过 appengine-web.xml 配置请求此功能。

请检查并投票!

https://code.google.com/p/googleappengine/issues/detail?id=10339&sort=-id&colspec=ID%20Type%20Component%20Status%20Stars%20Summary%20Language%20Priority%20Owner%20Log

于 2013-11-28T04:03:07.220 回答