【问题标题】:Content negotiation ignored when using browser Back button使用浏览器后退按钮时忽略内容协商
【发布时间】:2010-11-30 18:14:35
【问题描述】:

情况如下:

我有一个响应资源列表请求的 Web 应用程序,比如说:

/items

这最初是由网络浏览器通过导航到该路径直接请求的。浏览器使用它的标准“Accept”标头,其中包括“text/html”,我的应用程序注意到这一点并返回项目列表的 HTML 内容。

在返回的 HTML 中是一些 JavaScript (jQuery),然后执行 ajax 请求来检索实际数据:

/items

只有这一次,“Accept”标头被显式设置为“application/json”。同样,我的应用程序注意到了这一点,并且 JSON 被正确返回到请求中,数据被插入到页面中,一切都很顺利。

问题来了:用户导航到另一个页面,然后按下返回按钮。然后提示他们保存文件。这原来是项目列表的 JSON 数据。

到目前为止,我已经确认 Google Chrome 和 Firefox 3.5 都会发生这种情况。

这里有两种可能的答案:

  1. 如何解决此问题。是 有一些神奇的组合 Cache-Control 标头或其他 巫毒教导致浏览器做 这里是正确的吗?

  2. 如果你认为我在做某事 这里大错特错,我该怎么走 对这个?我正在寻求正确性, 但也尽量不牺牲 灵活性。

如果有帮助,该应用程序是一个 JAX-RS Web 应用程序,使用 Restlet 2.0m4。如果有帮助,我可以提供示例请求/响应标头,但我相信该问题是完全可重现的。

【问题讨论】:

  • 这看起来像是我在弄清楚 (stackoverflow.com/questions/5250923) 之后会遇到的一个未来问题。我很好奇,您最终是坚持使用此解决方案还是最终放弃了它以使用不同的 URL?对于同一资源的不同表示,单个 RESTful URL 的简洁性当然是理想的。

标签: ajax json web-applications jax-rs content-negotiation


【解决方案1】:

老问题,但是对于看到这个的其他人来说,提问者对 Accept 标头的使用没有任何问题。

这是 Chrome 中已确认的错误。 (以前也在 Firefox 中,但现在已修复。)

http://code.google.com/p/chromium/issues/detail?id=94369

【讨论】:

    【解决方案2】:

    我知道这个问题很老了,但以防万一其他人遇到这个问题:

    我在使用 jQuery 的 Rails 应用程序中遇到了同样的问题,我通过告诉浏览器不要缓存 JSON 响应来解决这个问题,这里给出了另一个问题的解决方案:

    jQuery $.getJSON works only once for each control. Doesn't reach the server again

    这个问题似乎只出现在 Chrome 和 Firefox 上。 Safari 可以很好地处理后退行为,而无需明确告诉它不要缓存。

    【讨论】:

    • 这个答案对我有用,如果你将 jQuery.ajax() 请求中的“缓存”选项设置为“false”,你可以回击它,它会按预期工作
    【解决方案3】:

    是否有一些 Cache-Control 标头或其他巫术的神奇组合导致浏览器在这里做正确的事情?

    如果您对不同的 Accept: 标头提供不同的响应,则必须包含标头:

    Vary: Accept
    

    在您的回复中。 Vary 标头还应包含影响响应的任何其他请求标头,因此例如,如果您执行 gzip/deflate 压缩,则必须包含 Accept-Encoding。

    不幸的是,IE 对 Vary 的许多值的处理很差,完全破坏了缓存,这对你来说可能或可能无关紧要。

    如果你认为我在这里做错了什么,我应该怎么做?

    我不认为在同一个 URL 上为不同类型提供不同内容的想法是非常错误的,但是你让自己陷入了比你真正需要的更多的兼容性问题。依靠通过 JSON 工作的标头在实践中并不是一个好主意。最好使用不同的 URL,例如 /items/json/items?format=json

    【讨论】:

    • 在同一个 URL 提供不同的资源是错误的;为同一资源提供不同的表示是 HTTP 应该做的。您想以 XML、JSON、格式良好的可读 HTML 或纯文本格式查看它吗?它总是一样的,但是你可以选择格式。不幸的是,一些浏览器破坏了这一点,你必须在响应中使用类似的 hack。如果您的服务同时提供“application/json”和“text/html”,Internet Explorer 将获取 JSON 版本,因为它的 Accept 标头有问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 2018-08-10
    • 2018-10-05
    • 2021-08-25
    • 2013-03-02
    • 1970-01-01
    相关资源
    最近更新 更多