【发布时间】:2015-12-01 16:46:08
【问题描述】:
我的 .NET MVC 控制器中有一些操作将返回常规请求的完整视图,但如果请求是 Ajax 请求则仅返回部分视图。
在控制器动作结束时...
if (HttpContext.Request.IsAjaxRequest())
{
return PartialView("_Partial", model);
}
else
{
return View(model);
}
在同一个控制器上,我设置了一些缓存选项,以便为 ajax 请求缓存一个结果,为常规请求缓存一个结果。
[OutputCache(Duration = 120, VaryByParam = "*", VaryByHeader="X-Requested-With")]
最后,我使用history.pushState 和onpopstate 事件控制历史记录,这样如果用户单击“返回”按钮,只有页面中会更改的部分会被重新加载。
jQuery(document).ready(function () {
if (history.pushState) {
$(window).on("popstate", function (e) {
FunctionThatUsesAjaxToRewriteThePage();
});
}
$('#SomeForm').on('submit', function (e) {
e.preventDefault();
var url = FunctionToGetUrlToUse();
if (history.pushState) {
history.pushState(null, null, url);
FunctionThatUsesAjaxToRewriteThePage();
}
else {
window.location.href = url;
}
});
});
这可以正常工作,但在 Google Chrome 中除外。有时,当我通过浏览器的后退和前进按钮导航到页面时,Chrome 会不恰当地呈现 AJAX 返回值而不是整个页面。
到目前为止,这似乎只有在我使用后退/前进按钮导航到不同页面(我的 MVC 站点上的另一个操作,或我的域上的另一个站点)然后使用返回到有问题的操作时才会发生后退或前进按钮。详细导航步骤:
- 我加载了我网站的主页 (http://mysite.co)。
- 我单击主页上的一个链接,指向使用所有 Ajax/history API 魔法的控制器操作 (http://mysite.co/month/2016/december)。
- 我单击了该页面中的一个链接,该链接触发了对主页内容 (http://mysite.co/month/2016/january) 的 ajax 重写。
- 我单击返回(触发 popstate 事件,URL 更改为 http://mysite.co/month/2016/december 并调用 AjaxRewrite 函数)。
- 我再次点击返回(返回http://mysite.co)。
- 我单击前进。这会将我返回到http://mysite.co/month/2016/december,但我没有获得完整页面,而是获得了该操作的 ajax 版本,这只是部分视图。
Firefox 和 IE 没有这种不当行为。
我试图解决的问题:
- 将输出缓存位置指定为仅服务器。即使在 Chrome 中清除缓存后,我仍然会在不应该的情况下获得 AJAX 版本的页面。
[OutputCache(Duration = 120, VaryByParam = "*", VaryByHeader="X-Requested-With", Location=OutputCacheLocation.Server)]
- 为 history.pushState 提供更多标准/可序列化对象
history.pushState({}, '', url);
或者
history.pushState({id: "foo"}, '', url);
-
根据HTML5 History API: JSON displayed when going "back" to another page, and then "forward" again,向 ajax 请求添加任意参数。
$.ajax ({ url: url, type: 'GET', traditional: true, contentType: 'application/json', data: { //all my normal URL parameters go here ajax: "true" }, //.....
【问题讨论】:
标签: asp.net-mvc html google-chrome caching html5-history