设想:
- 用户正在使用 IE9(IE8/10 不受影响)。
- 用户有一个活动会话。
SessionState(SessionStateBehavior.Required)
页面向具有属性(不受影响)的控制器发起 AJAX POST(GET 不受影响)请求ReadOnly
。有些东西阻止了这个请求被立即处理(例如另一个正在进行的请求,它已经锁定了会话)。- 当 AJAX POST 正在进行时,用户会离开页面(GET 或 POST - 无关紧要)
结果:
- AJAX POST 终止并返回 HTTP 500(浏览器已退出侦听,但您可以在 IIS 日志中看到它)。IIS 失败的请求跟踪显示错误为“指定的网络名称不再可用。(0x80070040)。”
- 在执行下一个需要读/写会话访问权限的请求之前,用户的会话被锁定 80 到 120 秒(通常约为 100 秒)。
进一步挖掘 IIS Failed Request Tracing 创建的日志表明,AJAX POST在会话状态被锁定后REQUEST_ACQUIRE_STATE
(在该阶段期间)像这样崩溃,但由于该REQUEST_RELEASE_STATE
阶段没有发生,因此不会释放会话锁。我假设有一些安全机制可以在 80-120 秒后解锁会话,但是这种很长的挂起显然对我的用户来说是不希望的。
我有一个简单的 VS2012/.Net 4.5/MVC4 项目,演示了https://github.com/jorupp/Ie9SessionCrash上的问题(有一个页面,通过睡眠调用发布了一系列关于操作的帖子)。显示问题的 IIS 失败请求跟踪位于https://github.com/jorupp/Ie9SessionCrash/tree/master/Ie9SessionCrash/TraceOfHttp500的项目中。
为了解决这个问题,我们计划确保我们永远不会对需要会话的操作进行任何 AJAX POST 调用,并且:
- 尽可能使用 GET 调用
SessionState(SessionStateBehavior.ReadOnly)
对具有该属性的控制器使用 POST 调用。
有没有更好的方法来处理这个问题,或者我是否缺少与此相关的 IIS/.Net 补丁?还是由于其他原因,这种情况无效?我不愿意为此责怪框架/IIS,但我认为我已经消除了我的代码错误。