为了提高网站的性能/响应能力,我使用AJAX,replaceState,pushState和popstate侦听器实现了部分页面加载。
我基本上将页面的中心部分(HTML)存储为历史记录中的状态对象。当单击链接时,我只从服务器请求页面的中心位(用不同的 Accept 标头标识这些请求)并将其替换为 javascript。在流行状态下,我抓住前一个中心部分并将其推回 dom。
这基本上可以正常工作,但是我发现了一个我坚持的特定问题。解释起来有点复杂,所以如果这不是很清楚,我深表歉意。
我们的大多数页面上都有一个搜索表单。通过 ajax 加载部分页面仅在 GET 请求上,表单执行 POST 导致整个页面加载。
如果我浏览以下一组页面,我最终会进入一个格式错误的部分页面,仅包含中心内容,而没有任何周围的 dom:
从主页开始(通过整页加载) - 执行搜索(重定向后获取)
将您带到搜索结果(通过整页加载) - 然后单击主页
返回到主页(通过动态获取) - 单击浏览器返回
搜索结果(来自流行状态侦听器)- 单击浏览器返回
主页格式不正确。
当出现格式错误的主页时,我的 popstate 侦听器根本不存在。
我认为正在发生的事情是,主页的第二次加载(动态,部分)被浏览器缓存,然后当整页返回时,浏览器仅显示缓存的部分响应而不是整个页面。
为了尝试解决此问题,我在响应中添加了一个 Vary: Accept 标头,让浏览器知道内容可能会根据接受标头而更改。我还在部分加载的内容中添加了 Cache-Control max-age=0、编译指示无缓存和过去的到期日期,以尝试强制浏览器不缓存此问题,但这些都无法解决。
不幸的是,我的公司不允许外部流量进入我们的开发服务器,所以我无法向您展示问题所在。我在这里看过各种类似的问题,但似乎都不完全相同,建议的解决方案似乎也不起作用。
如果我在我的动态GET请求中添加一个毫无意义的参数(blah=blah),这就解决了问题。然而,这是一个我宁愿不做的丑陋黑客。这似乎应该可以用标题解决,因为我认为这是一个缓存问题。谁能解释一下发生了什么?
这是一个缓存问题。将响应标头缓存控制设置为 no-cache
或 max-age=0
,问题不会发生在 FF 中(如您所说),但它在 Chrome 中仍然存在。
对我有用的标题是 缓存控制:no-store
.并非所有浏览器都一致地实现了这一点(您可以找到询问无缓存和无存储之间有什么区别的问题),但在Chrome中也有您所期望的结果。
我也有类似的问题。我正在构建一个基于 Web 的向导并使用 jquery ajax 加载每个步骤(后端 ASP.NET MVC)。
初始路由类似于/Questions/Show - 它加载整个页面并显示第一个问题(问题 0)。当用户单击下一张图片时,它会执行一个 jquery .load() 的网址为/Questions/Save/0 。这将保存答案并返回包含下一个问题的部分视图。下一个保存会使用/Questions/Save/1 执行 jquery .load() ...
我实现了历史记录.js以便用户可以来回(前?它将问题编号存储在状态数据中。当它检测到状态更改(并且状态的问题编号与页面上的问题不同)时,它会执行 jquery .load() 来加载正确的问题。
起初,我使用的路线与加载初始页面时相同(/Questions/Show/X,其中X是问题编号)。在后端,我检测到它是否是 ajax 请求,如果是,则返回部分视图而不是完整视图。 这就是问题出现的地方,类似于您的问题:假设我在问题 3 上,返回,然后向前,然后转到 www.google.com,然后点击后退按钮。 它显示了问题 3,但它是部分视图 - 因为浏览器缓存了该路由的部分视图。
我的解决方案是为 ajax 调用创建一个单独的路由:/Questions/Load/X(它在后端使用通用代码)。 现在有两个不同的路由(/Questions/Show for non-ajax 和/Questions/Load for ajax),浏览器在上述情况下可以正确显示整个页面。
所以也许类似的解决方案会适合你......即主页的两种不同路线 - 一条用于整页,一条用于部分。 希望有帮助。
当单击链接时,我只从服务器请求页面的中心位(用不同的 Accept 标头标识这些请求)并将其替换为 javascript。
棒。这是休息的方式。但是要使其正常工作,还有一件事要做:向响应添加Vary
标头。
Vary: Accept
这告诉浏览器具有不同 Accept 标头的请求可能会得到不同的响应。由于这两个请求使用不同的 Accept 标头,因此浏览器(和任何缓存代理)将分别缓存响应。
与设置Cache-Control: no-store
不同,这仍然允许您使用缓存。