6

我有一个可以通过 URL /products 访问的页面。当我在浏览器中访问它时,它会以布局中的完整页面进行响应。这是请求标头和响应正文的简化示例:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

<layout>
<products />
</layout>

当用户进行一些搜索时,javascript 会通过 AJAX 更新结果。结果是在没有布局的情况下渲染的,因为渲染需要时间,而且我也不需要它:

Accept: */*;q=0.5, text/javascript, application/javascript, application/ecmascript, application/x-ecmascript
X-Requested-With: XMLHttpRequest

<products />

所以,在我添加缓存之前,这工作得很好Cache-Control: private, max-age=3600。最初我虽然会添加Vary: X-Requested-With标题,但浏览器会区分这两个响应。但是,当我通过 AJAX 获取 /products 然后在浏览器中访问 /products 时,它会显示部分 AJAX 响应。

有没有简单的方法来解决这个问题?

PS 如果这很重要,我正在使用 Ruby on Rails 和 jQuery。

4

6 回答 6

1

让您的 Ajax 调用使用不同的 URL,例如 /products/partial。

于 2012-07-07T01:01:57.253 回答
0

Steve Luscher 的这篇文章描述了一个类似的案例,这个问题比你描述的更间歇性。建议的解决方案是:

  1. 在提交表单时取消所有 AJAX 请求

  2. 根据您期望的响应使用不同的 URL

Steve 在 ajax 请求中使用 cancel() 获得了第一名。

你没有提到你用过什么浏览器,这里有一个浏览器相关的问题

于 2012-07-12T22:06:57.633 回答
0

可能最简单的方法是将jquery的Ajax方法的'cache'参数设置为'False'。它会自动将时间戳附加到 URI 以防止它被缓存。

这可以使用以下代码段在应用程序范围内完成:

$.ajaxSetup({
    cache: false
});

如果缓存对于动态请求也很重要,您可以根据日期和小时自行生成时间戳。

于 2012-07-13T14:25:42.563 回答
0

使用Vary: Accept. 这应该有效。

于 2012-07-13T09:26:31.903 回答
0

尝试发送 must-revalidate 而不是 private (更适合代理)。

Cache-Control: max-age=3600, must-revalidate

我建议阅读这篇文章:http ://www.mnot.net/cache_docs/它可能会有所帮助。并且还使用 Mark 的工具http://redbot.org/来测试您的结果以消除您的本地机器或 isp 或其他什么。

于 2012-07-14T00:25:17.503 回答
0

对于部分结果,您应该有一个不同的 url(即 ?partial=yes 或类似的东西......)

或者

您可以通过 ajax 获取整个页面并使用 jquery.load() 仅提取您想要的部分。

$("#productsContainerHolder").load("/my/products/url #productsContainer", { myParam: "beer", myParam2: "cold"});

$.load 将使用“GET”方法调用您的服务器,检索所有内容,从那里提取#productsContainer 并插入“#productsContainerHolder”

<div id="productsContainerHolder">
    <div id="productsContainer>
         ...
    </div>
</div>
于 2012-07-10T16:29:10.487 回答