.NET MVC点击浏览器前进后退时恢复对应页面session变量值的方案咨询
问题根因
你遇到的现象本质是两个特性叠加导致的:
- Session是服务端的全局状态存储,本身不会自动记录历史版本,只会保留最新的写入值
- 浏览器点击后退按钮时,默认会优先加载本地缓存的历史页面,不会向服务器发起新请求,控制器对应的Action代码根本不会被触发,自然无法更新页面数据
无需AJAX、控制器侧即可实现的首选方案
直接通过禁用指定页面的缓存,强制浏览器后退时重新发起请求到控制器,同时将页面对应的ID从全局Session改为和请求绑定的路由/查询参数,完全避免依赖全局状态:
- 首先实现一个无缓存过滤器,强制浏览器不缓存对应页面:
public class NoCacheAttribute : ActionFilterAttribute { public override void OnResultExecuting(ResultExecutingContext filterContext) { filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1)); filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false); filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache); filterContext.HttpContext.Response.Cache.SetNoStore(); base.OnResultExecuting(filterContext); } }
- 将特性标记到你需要处理的Action上,同时修改Action的参数接收规则,从路由/查询参数取ID,不再依赖Session存储的ID:
[NoCache] public ActionResult YourPage(int id) { // 直接用当前请求携带的id加载对应数据,不受全局Session最新值影响 var pageData = GetBusinessDataById(id); return View(pageData); }
修改之后,用户点击后退按钮时,浏览器会携带对应历史页面的路由参数重新请求控制器,直接就能加载到匹配的页面数据,完全不需要前端AJAX参与。
其他可行解决方案
- 将页面对应的ID直接写到视图的隐藏字段、路由参数或者查询字符串中,和页面本身绑定,彻底和服务端Session的全局状态解耦,不需要修改任何服务端缓存逻辑就能适配后退场景
- 如果必须保留Session的使用,可以在Session中维护一个ID的历史栈,每次访问新页面时将当前ID压入栈,前端监听
popstate后退事件时通知服务端弹出栈顶的历史ID,再刷新页面即可加载对应数据 - 利用浏览器History API将对应页面的ID存入历史状态对象中,每次页面触发
pageshow事件时读取状态中的ID,提交给控制器加载对应数据,不需要依赖服务端状态
内容的提问来源于stack exchange,提问作者sonali
相关产品推荐
相关产品推荐

