1

我有以下情况:

  • 用户向显示表单的 PAGE A 发出请求(服务器存储此页面的缓存)
  • 用户将表单提交给用于表单提交的 CONTROLLER
  • CONTROLLER 在用户提交的数据中发现错误,设置一个 cookie ERRORS 详细说明,并将用户重定向回 PAGE A
  • PAGE A 显示原始内容加上 ERRORS(服务器存储此页面的缓存)
  • PAGE A 删除 ERRORS cookie

这有效,但前提是我不在系统上为 PAGE A 使用缓存。

问题是,在删除 cookie 后,浏览器在没有 cookie 的情况下向我的服务器发出请求并收到 304 Not Modified 错误,因此,浏览器仍然显示有错误的页面,而不是没有(来自原始请求)。服务器正确存储缓存(对于有错误的页面以及无错误的页面)。

基本上,服务器现在有两个缓存页面:PAGE A 和 PAGE A WITH ERRORS。

浏览器,其最后一个已知页面是 PAGE A WITH ERRORS 向服务器请求具有 PAGE A 条件的页面,而不是 PAGE A WITH ERRORS,因为 cookie 不再存在。但它认为 304 响应是关于 PAGE A WITH ERRORS,而不是 PAGE A。我什至检查了浏览器发送的数据,它知道它使用 ERRORS cookie 获得了 PAGE A WITH ERRORS,但接受 304 not modified when在没有该 cookie 的情况下发出请求。它不会根据创建它的条件验证自己的缓存。

浏览器不使用它设置的 cookie 验证它的缓存吗?

在不为每个请求设置一些 GET 变量的情况下,是否有解决方法?另一种选择是告诉服务器永远不要缓存具有此类错误状态集的页面,但这将是一种黑客攻击。

4

3 回答 3

2

显然解决方案是将其作为响应标头包含在内:

Vary: Cookie

这将在缓存引擎中考虑 cookie。

编辑:

但是有一个问题:Chrome、Internet Explorer 和 Firefox 可以正常工作,但是 Safari 和 Opera 在存储和验证缓存时都忽略了“Vary”标头。

于 2012-10-23T12:49:30.867 回答
1

对于这种情况,客户端会话(又名 cookie)可能还不够……建议改为使用服务器端会话。即使 Vary 标头可能有效 - 使用 $_SESSION 您将处于保存状态。

于 2012-10-24T00:04:53.117 回答
0

Cache-control: public 可能不是你想要的。Public 本质上说您正在使用静态的、全局可访问的数据。它不会因用户而异。它是全局缓存的,因为您声称数据是全局的。

一旦您开始按用户更改,缓存就会违反他们的假设。“私人”更类似于您想要的。

但是,这将意味着您获得的良好中间人缓存会减少。您可以通过重新验证或适当使用 Vary 标头来达到一些中间立场。

于 2012-10-23T11:27:35.097 回答