可以使用卸载事件可靠地激活ajax请求吗?

时间:2010-08-27 12:51:31

标签: javascript ajax events reliability

我需要一种方法来监控用户编辑会话,我正在审查的其中一个解决方案将让我使用unload事件发送ajax请求,以通知服务器编辑会话结束。 (见:Monitoring User Sessions to Prevent Editing Conflict

unload事件上的(相当有限的)读数表明附加到此处理程序的代码必须快速运行,因此通常用于清除对象以防止内存泄漏。

我的问题是,这可以为此目的提供足够的可靠性吗?

PS。我知道async: false选项。

5 个答案:

答案 0 :(得分:36)

如果您的服务器足够快以响应,则此方法相当可靠。值得注意的事情。如果关闭浏览器并在卸载事件上发送AJAX请求,则很有可能在窗口对象被销毁之前,响应不会及时从服务器返回。在这种情况下(至少在IE中)会发生什么情况,它将孤立您的连接对象,并且在连接超时被触发之前不会正确终止它。如果您的服务器没有打开连接保持活动,关闭2个窗口(同时仍然打开另一个窗口),您将没有打开到服务器的连接(对于IE6-7,对于IE8 - 6个窗口)在达到连接超时之前,您将无法打开您的网站。

我遇到过这样的情况之前,我正在打开一个弹出窗口,在卸载时发送一个AJAX请求,它非常可靠,但它被上面描述的发布所困扰,而且我花了很长时间追踪它并了解正在发生的事情。之后,我做了,我确保打开窗口将具有相同的代码来调用服务器,并在每次卸载时检查开启器并在那里运行代码(如果它存在)。

似乎如果你关闭最后一个浏览器窗口,IE会正确地破坏连接,但如果另一个窗口打开,它就不会。

P.S。只是为了评论上面的答案,AJAX并不是真正的异步。至少JS的实现不是。发送请求后,您的JS代码仍将等待来自服务器的响应。它不会阻止您的代码执行,但由于服务器可能需要一段时间才能响应(或者Windows足以终止IE窗口对象),您可能会遇到上述问题。

答案 1 :(得分:12)

您是否尝试过使用

var i = new Image(1,1); 
i.src='http://...'

只是从服务器返回一些空图像。我认为应该可靠,脚本会阻止。顺便说一句:很高兴添加时间戳来防止缓存。

答案 2 :(得分:3)

我们有一个需要的情况。这是一个报告页面,需要服务器上的大量内存,所以我们想在它们离开页面后立即释放它。我们创建了一个框架集并在那里添加了卸载处理程序。最可靠的方法是将图像的src设置为释放脚本。我们实际上使用了unload和onbeforeunload来实现跨浏览器的兼容性。它在网络套件中没有用,但管理层对此没有问题。

但是,这不是我提出的解决方案。我会使用心跳方法,这涉及更多的工作,但更强大。

您的页面应发送定期心跳请求。每个请求都设置页面的最后一次心跳。然后,您需要一个在服务器上运行的线程,如果最后一次心跳太久,则需要清除内存。

这并不能解决长时间停留页面的问题。为此,您需要对用户活动进行一些监控,并在一段时间不活动后离开该页面(确保您与用户确认)

答案 3 :(得分:1)

你必须自己测试你的特定场景是否与你在unload中的时间一致,但由于AJAX是异步的,因此使得AJAX请求非常快。您只需发送请求,然后就完成了! (也许你必须清除你刚创建的请求对象。)

如果您想验证AJAX请求是否成功,那么您必须担心更多/使用async:false选项(如this discussion表示)。但是,只是发送是一个快速繁荣和你完成的操作。

答案 4 :(得分:-2)

我有一个案例,我只需要通知服务器端有关卸载的事情,并且不关心响应。

如果是你的情况,你可以ignore_user_abort,然后你知道它会发生"可靠"