.NET MVC 缓存、Chrome、具有可变结果的操作和 HTML5 历史 API
.NET MVC Cache, Chrome, Actions with Variable Results, and the HTML5 history API
我的 .NET MVC 控制器中有一些操作可以 return 常规请求的完整视图,但如果请求是 Ajax 请求,则只有部分视图。
控制器动作结束时...
if (HttpContext.Request.IsAjaxRequest())
{
return PartialView("_Partial", model);
}
else
{
return View(model);
}
在同一个控制器上,我设置了一些缓存选项,这样一个结果应该为 ajax 请求缓存,一个结果为常规请求缓存。
[OutputCache(Duration = 120, VaryByParam = "*", VaryByHeader="X-Requested-With")]
最后,我使用 history.pushState and the onpopstate 事件控制历史记录,这样如果用户单击 "back" 按钮,只有页面中发生变化的部分会被重新加载。
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 return 值而不是整个页面。
到目前为止,这似乎只有在我使用 back/forward 按钮导航到另一个页面(我的 MVC 站点上的另一个操作,或者我域中的另一个站点)然后 return 使用后退或前进按钮转到违规操作。详细导航步骤:
- 我加载我网站的主页 (http://mysite.co)。
- 我在主页上单击一个 link 到使用所有 Ajax/history API 魔法 (http://mysite.co/month/2016/december) 的控制器操作。
- 我在该页面中单击了 link,触发了主页内容的 ajax 重写 (http://mysite.co/month/2016/january)。
- 我单击返回(触发 popstate 事件,URL 更改为 http://mysite.co/month/2016/december 并且 Ajax 重写函数被调用)。
- 我再次点击返回(回到http://mysite.co)。
- 我点击前进。这 return 将我引导至 http://mysite.co/month/2016/december,但我只获得了 ajax 版本的操作,而不是整个页面,这只是部分视图。
Firefox 和 IE 没有这种错误行为。
我试图解决的事情:
- 仅将输出缓存位置指定为服务器。即使在 Chrome 中清除缓存后,我仍然会在不应该的时候得到页面的 AJAX 版本。
[OutputCache(Duration = 120, VaryByParam = "*", VaryByHeader="X-Requested-With", Location=OutputCacheLocation.Server)]
- 将更多 standard/serializable 个对象提供给 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"
},
//.....
没关系!实际上我尝试的第三件事(向 AJAX 请求添加一个虚拟参数)确实有效,但是我需要清除我的缓存在 Chrome 之前我会看到结果。
简而言之,这样做:
$.ajax
({
//...
data: {
//...your data here
ajax: "true" //Add this line or one like it to differentiate AJAX requests
},
然后 然后 清除 Chrome 中的缓存(Ctrl+Shift+Del 用于 Windows 或 Shift+Command+Del 用于 Mac).
我的 .NET MVC 控制器中有一些操作可以 return 常规请求的完整视图,但如果请求是 Ajax 请求,则只有部分视图。
控制器动作结束时...
if (HttpContext.Request.IsAjaxRequest())
{
return PartialView("_Partial", model);
}
else
{
return View(model);
}
在同一个控制器上,我设置了一些缓存选项,这样一个结果应该为 ajax 请求缓存,一个结果为常规请求缓存。
[OutputCache(Duration = 120, VaryByParam = "*", VaryByHeader="X-Requested-With")]
最后,我使用 history.pushState and the onpopstate 事件控制历史记录,这样如果用户单击 "back" 按钮,只有页面中发生变化的部分会被重新加载。
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 return 值而不是整个页面。
到目前为止,这似乎只有在我使用 back/forward 按钮导航到另一个页面(我的 MVC 站点上的另一个操作,或者我域中的另一个站点)然后 return 使用后退或前进按钮转到违规操作。详细导航步骤:
- 我加载我网站的主页 (http://mysite.co)。
- 我在主页上单击一个 link 到使用所有 Ajax/history API 魔法 (http://mysite.co/month/2016/december) 的控制器操作。
- 我在该页面中单击了 link,触发了主页内容的 ajax 重写 (http://mysite.co/month/2016/january)。
- 我单击返回(触发 popstate 事件,URL 更改为 http://mysite.co/month/2016/december 并且 Ajax 重写函数被调用)。
- 我再次点击返回(回到http://mysite.co)。
- 我点击前进。这 return 将我引导至 http://mysite.co/month/2016/december,但我只获得了 ajax 版本的操作,而不是整个页面,这只是部分视图。
Firefox 和 IE 没有这种错误行为。
我试图解决的事情:
- 仅将输出缓存位置指定为服务器。即使在 Chrome 中清除缓存后,我仍然会在不应该的时候得到页面的 AJAX 版本。
[OutputCache(Duration = 120, VaryByParam = "*", VaryByHeader="X-Requested-With", Location=OutputCacheLocation.Server)]
- 将更多 standard/serializable 个对象提供给 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" }, //.....
没关系!实际上我尝试的第三件事(向 AJAX 请求添加一个虚拟参数)确实有效,但是我需要清除我的缓存在 Chrome 之前我会看到结果。
简而言之,这样做:
$.ajax
({
//...
data: {
//...your data here
ajax: "true" //Add this line or one like it to differentiate AJAX requests
},
然后 然后 清除 Chrome 中的缓存(Ctrl+Shift+Del 用于 Windows 或 Shift+Command+Del 用于 Mac).