Post / Redirect上的整页重新加载/忽略缓存控制

时间:2010-06-09 09:50:43

标签: caching google-chrome safari webkit post-redirect-get

我有一个页面加载了很多图像,CSS和JavaScript。我已经添加了一个远期的Expires头,并在这些外部依赖项上将Cache-Control设置为public,因此它们应该被缓存。但是每次我执行Post / Redirect / Get chrome都会尝试再次加载它们。此行为与重新加载页面非常相似。我添加了ETag并处理了If-None-Match标头,它有点帮助,但它仍然会产生太多无用的请求。

如何告诉chrome和safari从缓存中获取文件?

chrome   NOK
safari   NOK
firefox  OK
ie       OK

另请参阅Google支持论坛上的Full page reload on Post/Redirect/Get ignoring cache control

澄清:

我不希望浏览器两次请求image1.png。它应该被缓存。

200 GET  page1.html
200 GET  image1.png (Cache-Control: public, Expires and ETag)
302 POST action.asp (form submitted from page1.html, redirects)
200 GET  page2.html
304 GET  image1.png (If-None-Match)

示例:

我创建了一个简单的例子来说明问题。

http://crydust.be/lab/prg/

接头

我随图片发送的标题是:

HTTP/1.1 200 OK
Date: Fri, 18 Jun 2010 11:30:22 GMT
Server: Apache
Cache-Control: public, max-age=86400
Expires: Sat, 19 Jun 2010 11:30:24 GMT
Etag: "123"
Content-Length: 866
Content-Type: image/png

哪个应该让它缓存24小时。没有变化:*或类似的东西。

更新 此行为现​​在也出现在iOS 4上的Safari Mobile中。页面加载速度的可怕回归。

更新 在webkit bugzilla中有关于此问题的错误报告。 Bug 38690 - Submitting a POST that leads to a server redirect causes all cached items to redownload

更新 问题在iOS 4.0.1上仍然存在

更新 问题在iOS 4.1上仍然存在

更新 问题在iOS 4.2上仍然存在

更新 问题仍然存在于iOS 4.2.1上 在Chrome中从版本6到9。

更新 Chromium项目中有关于此问题的错误报告。 (你可以给它看星星以示你关心) Issue 68621: Post/Redirect/Get ignoring cache instructions

更新 从版本6到10,Chrome上的问题仍然存在。 它现在是一个9个月大的虫子。

更新 此问题已于2011-03-21 19:33:07太平洋标准时修复。这反映在chrome 12(金丝雀)的行为中。

3 个答案:

答案 0 :(得分:1)

当您在Chrome,Safari或IE8中进行F5 /刷新时,即使它们已被缓存,也会再次请求所有GET资源。

如果您使用开发工具或Fiddler观察请求/响应,您将看到服务器以HTTP 304状态响应并且没有内容。这告诉浏览器他们不需要再次下载它们,并且他们可以继续使用缓存。

在Chrome的开发工具'资源标签文件中刷新,这样会有延迟时间,但下载时间为0毫秒。

如果您通过离开并返回来重新加载页面,则会发现不会再次检索这些缓存的文件,并且不会检查服务器。

GET静态资源的F5 /刷新行为是正确的 - 它的FX和IE6做错了。它还有助于解决大多数用户不知道的令人困惑的CTRL + F5命令。

您无法缓存POST或返回临时HTTP重定向的页面:

POST更改数据,应始终在再次发送之前提示,并且其结果永远不会被缓存。

重定向在HTTP内容中以低级别处理 - 在缓存之下。它确实告诉浏览器从其他地方获取资源,虽然它可以缓存它没有缓存重定向并需要再次检查。

您应该能够缓存301永久重定向,但不应缓存302或303临时重定向according to the HTTP spec

答案 1 :(得分:0)

F5会在某些浏览器中重新加载所有页面的资源,因此它们会忽略缓存标头并再次请求每个资源。

如果你想“缓存”POST页面,你必须在静态资源中转换这些页面,例如从.php生成.html文件,然后将.html作为静态资源提供。

仅在页面内容未发生变化时才有效

答案 2 :(得分:0)

修复:cache-control: no-store

(您可能还希望使用状态代码307代替302,这将保留该方法。)

this open WebKit bug的评论中找到了解决方案 - 经过多天的挫折之后发现:

  

CachedRawResource现在保留了重定向链,并且具有一些用于检查正确性的简单逻辑,但它远未完成(仅检查cacheControlContainsNoStore())。当然,其他资源类型也没有。