Ajax的同步调用场景——使用同步Ajax在 onunload 事件时通知服务器_jlds123的博客-程序员宅基地

技术标签: server  浏览器  xmlhttprequest  asynchronous  ajax  prototype  

在一种场景下,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也不造成什么负担。
相关参考资料:
Making AJAX calls onUnload:  http://www.livelearncode.com/archives/11
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/jlds123/article/details/5995221

智能推荐

CentOS下mysql数据库常用命令总结-程序员宅基地

CentOS下mysql数据库常用命令总结mysql数据库使用总结本文主要记录一些mysql日常使用的命令,供以后查询。1.更改root密码mysqladmin -uroot password 'yourpassword'2.远程登陆mysql服务器mysql -uroot -p -h192.168.137.10 -P33063.查询数据库...

Dell EMC PowerEdge 配置 iDRAC_dell poweredge http管理界面-程序员宅基地

打开受管理的系统。 在开机自检(POST)过程中按。 在系统设置主菜单页面中,单击iDRAC Settings(iDRAC设置)。随即显示iDRAC Settings(iDRAC设置)页面。 单击"Network(网络)"。随即显示Networking(网络)页面。 指定网络设置。在"Enable NIC"(启用NIC)下面,选择Enabled(启用)。-Shared LOM(共享LOM)(1、2、3或4)将共享主板上的其中一个NIC -Dedicate..._dell poweredge http管理界面

7-1 实验10_9_指针数组进阶 (100 分)_从键盘上输入n个字符串(每个字符串的长度小于20,字符串包含空白字符),对其进行升_ChaoYue_miku的博客-程序员宅基地

7-1 实验10_9_指针数组进阶 (100 分)已知正整数n,n的范围是1—100。你要从键盘读入n个字符串,每个字符串的长度不确定,但是n个字符串的总长度不超过100000。你要利用字符指针数组将这n个字符串按照ASCII码顺序进行升序排序,然后再打印到屏幕上。字符串中可能包含ASCII码中的任意字符,每个字符串以换行符结束输入。要求:不允许定义如char str[100][100000];这样的二维数组,因为会极大的浪费内存空间。你应定义char str[100000];这样的存储空间,将n个字符_从键盘上输入n个字符串(每个字符串的长度小于20,字符串包含空白字符),对其进行升

由于不能验证所收到的数据是否可信,无法显示您想要查看的页面。建议向此网站的管理员反馈这个问题。_由于不能验证所收到的数据是否可信,无法显示您想要查看的页面。 建议向此网站的管_都什么什么啊的博客-程序员宅基地

代理服务器的问题https://tieba.baidu.com/p/5771890231但是有些网站还是打不开啊_由于不能验证所收到的数据是否可信,无法显示您想要查看的页面。 建议向此网站的管

使用Mybatis/TkMybatis/Mybatis-Plus框架报错:无效的列类型: 1111_mybatis-plus 写入oracle报错1111-程序员宅基地

使用Mybatis/TkMybatis/Mybatis-Plus框架报错:无效的列类型: 1111_mybatis-plus 写入oracle报错1111

python与openssl 进行rsa签名与验证_crypto库生成的签名值要经过反序后才能由openssl库进行验证-程序员宅基地

1、Python生成RSA秘钥,与签名验证# rsa签名,保存私钥公钥到本地from cryptography.hazmat.primitives.asymmetric import paddingfrom cryptography.hazmat.primitives import hashesfrom cryptography.hazmat.primitives import serializationfrom OpenSSL import cryptorsa_key = crypto.r_crypto库生成的签名值要经过反序后才能由openssl库进行验证

随便推点

【Java8新特性】Optional类-程序员宅基地

文章目录1 概述2 Optional类的方法3 总结参考资料1 概述到目前为止,臭名昭著的空指针异常是导致Java应用程序失败的最常见原因。以前,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类, Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。受到GoogleGuava的启发,Optional类已经成为Java8类库的一部分。Optional<T>类(java.util.Optional) 是一个容器类,它可以保存类型T的值,

Oracle AWR报告详细分析--比较详细-程序员宅基地

https://blog.csdn.net/demonson/article/details/79474133转载于:https://www.cnblogs.com/ritchy/p/10460984.html_oracle awr最好多长

Windows10在线安装Selenium遇到的问题(超时和没有权限)_selenium wos you don't have permission-程序员宅基地

Windows10在线安装Selenium遇到的问题(超时和没有权限)1.安装时出现超时2.安装时提示没有权限具体遇到问题的解决方案:1.在cmd进入命令行:pip install selenium,结果提示安装失败排查:原因是因为超时解决方案:因为超时了,所以加上超时时间。命令行:pip --default-timeout=150 install selenium..._selenium wos you don't have permission

google搜索的使用-程序员宅基地

你真的会使用google么? 如今遇到问题都会在搜索引擎中寻找答案,如何快速准确的寻找出你xiang

蓝桥试题 算法提高 字母大小写转换 JAVA-程序员宅基地

问题描述  从键盘输入一个字符,如果是大写字母(A-Z),就转换成小写;如果是小写字母(a-z),就转换成大写,如果是其他字符原样保持并将结果输出。输入格式  输入一行,包含一个字符。输出格式  输出一行,即按照要求输出的字符。样例输入a样例输出A思路:直接转成字符数组,然后利用ASCII码值,就可,结果千算万算没算出来这个居然还要求了 @ ( * . ?这几个字符,然后我的代...

JavaScript小练习4-鼠标移入移出改变样式_网购界面鼠标移入变化 条件渲染 js-程序员宅基地

题目移出:移入:分析思路清晰,onmouseover和onmouseout的使用,注意的地方有:width和height设置的是content的内容,padding和border要注意设置,实现前后大小相同,就要让整个盒子大小一致,即border也进行设置。cssText设置内联样式,cssText=""可清空内联样式。之前没明白onload的作用,这次理解了,之前onload..._网购界面鼠标移入变化 条件渲染 js

推荐文章

热门文章

相关标签