我需要一种方法来监控用户编辑会话,我正在审查的解决方案之一将使用unload
事件发送ajax请求通知服务器编辑会话已结束。(参见:Monitoring User Sessions to Prevent Editing Conflict)
我(相当有限的)阅读关于unload
事件的资料表明,附加到此处理程序的代码必须快速运行,并且通常用于清除对象以防止内存泄漏。
我的问题是,这个方法能够可靠地达到这个目的吗?
PS. 我知道async: false
选项。
我需要一种方法来监控用户编辑会话,我正在审查的解决方案之一将使用unload
事件发送ajax请求通知服务器编辑会话已结束。(参见:Monitoring User Sessions to Prevent Editing Conflict)
我(相当有限的)阅读关于unload
事件的资料表明,附加到此处理程序的代码必须快速运行,并且通常用于清除对象以防止内存泄漏。
我的问题是,这个方法能够可靠地达到这个目的吗?
PS. 我知道async: false
选项。
如果你的服务器响应速度足够快,这种方法是相当可靠的。但需要注意的是,如果在卸载事件上关闭浏览器并发送 AJAX 请求,很有可能在窗口对象被销毁之前无法及时从服务器获得响应。在这种情况下(至少在IE中),会使连接对象变成孤儿并且不会正确终止连接,直到连接超时时间到达。如果你的服务器没有打开持久连接,当你关闭两个窗口(同时还保留另一个窗口打开)后,你将没有足够的连接打开向该服务器发出请求(对于IE6-7而言,对于IE8而言则是6个窗口),直到连接超时时间到达你才能再次打开网站。
我曾遇到过这样的情况,我正在打开一个弹出窗口,在unload事件上发送了一个AJAX请求,它非常可靠,但是它被上述问题所困扰,并且我花费了很长时间来追踪并理解发生了什么。之后,我确保打开窗口具有与调用服务器相同的代码,并在每次unload时检查opener是否存在,如果存在则在此运行代码。
似乎如果你关闭最后一个浏览器窗口,IE会正确地销毁连接,但如果有其他窗口打开,则不会。
另外,值得一提的是,上面的答案中提到的,AJAX不是真正的异步。至少JS实现不是。在发送请求后,你的JS代码仍将等待服务器响应。它不会阻止你的代码执行,但由于服务器可能需要一段时间才能响应(或者足够长以使Windows终止IE窗口对象),你很可能会遇到上述问题。
你尝试过使用吗?
var i = new Image(1,1);
i.src='http://...'
只需从服务器返回一些空图像。 我认为它应该是可靠的,脚本将被阻止。 顺便说一句:很好地添加时间戳以防止缓存。
frameset
、图像和释放脚本方法吗?这似乎有些hackish...或者相比使用两个 unload
事件,这更可靠吗? - Yi Jiang你需要自己测试一下,看看你的特定情况是否能在“unload”中使用,但是由于AJAX是异步的,发送AJAX请求非常快。你只需发送请求,然后就完成了!(也许你还需要清除刚刚创建的请求对象)
如果你想验证AJAX请求是否成功,那么你就需要更担心,使用async:false
选项(如this discussion所示)。但是,只发送请求就是一个快速的操作。
Navigator.sendBeacon
,它将允许更可靠地在卸载时向服务器发出异步请求的更好方式:https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon - Wildhoney