Ajax的同步调用场景——使用同步Ajax在 onunload 事件时通知服务器
2010-11-08 14:02
253 查看
在一种场景下,server端维护了浏览器客户端的状态信息,当浏览器关闭时需要立刻通知
server用户已经
离开了,server端好清理状态。这种情况的典型案例就是:浏览器客户端的即时通信,即web
IM。因为用户关闭了窗口就表明用户已经不在线了,所有对话都结束了,server端和对话的另一方需要立刻知道这个状态变化。而一般情况
下,server端并不需要立刻通知
的情况,那就无所谓了,只要过期超时即可。
要想在用户关闭浏览器后,server端得到通知,一般有两种做法:
方法一
:通过 javascript 轮询的方式向 server
发送心跳(使用异步ajax),server端记下上次心跳时间,server端Timer定期检查会话的心跳时间是否超时来判断用户是否已经离开了。这
种方法的缺点是,要想即时通知就得把心跳间隔时间设得短,server端检查的时间也要短,这样会导致server端的负担大大增加,所能承载的用户就会
较少。
方法二
:不采用发送心跳的方式,而是在用户关闭浏览器时,通知server即可。这样server端的负担就小了。
window.onunload = function(){
ajax.callServer();
}
重点说一下方法二的实现。
首先
,页面上注册 onunload 事件。如 body元素的 onunload 属性,或直接设置 window.onunload 。
注意是 onunload 而不是 onbeforeunload 事件,因为用户可以在 onbeforeunload 事件时选择“取消”从而不关闭窗口,而onunload 事件意味着窗口肯定是要被关闭的。
其次
,在onunload事件中调用同步的ajax请求通知server,而非默认的异步ajax请求
。
因为调用异步的ajax请求在一些浏览器下无法真正使server得到通知,实际上根本无法保障!在发出了这个异步请求之后,浏览器就要关闭窗口并清理所
有相关资源,因为这是异步请求,所以浏览器有理由认为无需等待该请求完成即可开始关闭窗口,这样该请求就可能失败(IE上就是这样,用异步请求无法通知到
server)。这也解释了为什么异步callServer()调用后面再加个alert语句就没问题了,因为alert语句在后面挡着,需要人来点确
认,所以可以完成对server的请求。而用同步的ajax请求则浏览器会等待该请求完成后才关闭窗口清理资源,因而就不会有这个问题。
这就是一种使用同步ajax的场景,ajax中第一个a指的是 asynchronous
异步,当初引入ajax的主要目的就是引入一种异步执行的方法,绝大部分情况下应该使用异步方式执行ajax。同步ajax也许应该叫做 sjax ( s
是 synchronously)。
XMLHttpRequest 的 open 方法中的第三参数表示是同步还是异步,xmlHttp.open("GET", url, true); 各种支持Ajax的框架,如prototype、ext、dwr等肯定都有选项设置是否为异步模式。
最后,实际情况的做法是要结合方法一和方法二
。方法二由于各种原因(比如用户电脑突然停电、浏览器崩溃等,
这你总没办法吧),总是难免浏览器在关闭时没有成功的通知server。尽管是少数情况,但server端是要保证长期运行稳定的,要避免资源泄漏,所以
必然server端还是需要定期检查会话是否过期的。但因为已经保证了大部分情况下server得到了通知,所以server端的定期检查可以时间长一
些,心跳间隔也可以时间长一些(但要小于server检查的时间间隔),因而对server也不造成什么负担。
相关参考资料:
Snippets: Synchronous AJAX: http://www.hunlock.com/blogs/Snippets:_Synchronous_AJAX
Making AJAX calls onUnload: http://www.livelearncode.com/archives/11
server用户已经
离开了,server端好清理状态。这种情况的典型案例就是:浏览器客户端的即时通信,即web
IM。因为用户关闭了窗口就表明用户已经不在线了,所有对话都结束了,server端和对话的另一方需要立刻知道这个状态变化。而一般情况
下,server端并不需要立刻通知
的情况,那就无所谓了,只要过期超时即可。
要想在用户关闭浏览器后,server端得到通知,一般有两种做法:
方法一
:通过 javascript 轮询的方式向 server
发送心跳(使用异步ajax),server端记下上次心跳时间,server端Timer定期检查会话的心跳时间是否超时来判断用户是否已经离开了。这
种方法的缺点是,要想即时通知就得把心跳间隔时间设得短,server端检查的时间也要短,这样会导致server端的负担大大增加,所能承载的用户就会
较少。
方法二
:不采用发送心跳的方式,而是在用户关闭浏览器时,通知server即可。这样server端的负担就小了。
window.onunload = function(){
ajax.callServer();
}
重点说一下方法二的实现。
首先
,页面上注册 onunload 事件。如 body元素的 onunload 属性,或直接设置 window.onunload 。
注意是 onunload 而不是 onbeforeunload 事件,因为用户可以在 onbeforeunload 事件时选择“取消”从而不关闭窗口,而onunload 事件意味着窗口肯定是要被关闭的。
其次
,在onunload事件中调用同步的ajax请求通知server,而非默认的异步ajax请求
。
因为调用异步的ajax请求在一些浏览器下无法真正使server得到通知,实际上根本无法保障!在发出了这个异步请求之后,浏览器就要关闭窗口并清理所
有相关资源,因为这是异步请求,所以浏览器有理由认为无需等待该请求完成即可开始关闭窗口,这样该请求就可能失败(IE上就是这样,用异步请求无法通知到
server)。这也解释了为什么异步callServer()调用后面再加个alert语句就没问题了,因为alert语句在后面挡着,需要人来点确
认,所以可以完成对server的请求。而用同步的ajax请求则浏览器会等待该请求完成后才关闭窗口清理资源,因而就不会有这个问题。
这就是一种使用同步ajax的场景,ajax中第一个a指的是 asynchronous
异步,当初引入ajax的主要目的就是引入一种异步执行的方法,绝大部分情况下应该使用异步方式执行ajax。同步ajax也许应该叫做 sjax ( s
是 synchronously)。
XMLHttpRequest 的 open 方法中的第三参数表示是同步还是异步,xmlHttp.open("GET", url, true); 各种支持Ajax的框架,如prototype、ext、dwr等肯定都有选项设置是否为异步模式。
最后,实际情况的做法是要结合方法一和方法二
。方法二由于各种原因(比如用户电脑突然停电、浏览器崩溃等,
这你总没办法吧),总是难免浏览器在关闭时没有成功的通知server。尽管是少数情况,但server端是要保证长期运行稳定的,要避免资源泄漏,所以
必然server端还是需要定期检查会话是否过期的。但因为已经保证了大部分情况下server得到了通知,所以server端的定期检查可以时间长一
些,心跳间隔也可以时间长一些(但要小于server检查的时间间隔),因而对server也不造成什么负担。
相关参考资料:
Snippets: Synchronous AJAX: http://www.hunlock.com/blogs/Snippets:_Synchronous_AJAX
Making AJAX calls onUnload: http://www.livelearncode.com/archives/11
相关文章推荐
- Ajax同步的调用场景——使用同步Ajax在 onunload 事件时通知服务器
- Ajax的同步调用场景——使用同步Ajax在 onunload 事件时通知服务器
- Ajax的同步调用场景——使用同步Ajax在 onunload 事件时通知服务器
- 服务器控件使用js进行验证(选择地调用后台事件)
- 深刻理解ajax中同步和异步的区别和使用场景
- 使用AJAX控件来实现Ajax操作(支持服务器事件)
- 使用ASP.NET AJAX开发服务器端事件通知器
- AJAX中同步和异步的区别和使用场景
- 服务器控件使用Javascript进行验证(选择地调用后台事件)
- 使用AJAX控件来实现Ajax操作(支持服务器事件)
- 使用ajax+js前台调用后台事件
- 使用SpringMvc跨服务器上传图片,Ajax异步刷新图片框显示图片功能请求不到后台,onChange事件没有激活的源码?
- 使用javascript调用服务器的事件
- AJAX同步和异步的区别及使用场景
- 服务器控件使用js进行验证(选择地调用后台事件)
- 一套使用简单的Ajax服务器控件-Anthem.NET
- 使用ajaxFileUpload上传文件流至服务器,同时提交多个参数
- 探讨jQuery的ajax使用场景(c#)
- Linux中使用rsync实现多服务器之间文件同步问题
- 使用HttpPost请求方式调用服务器