因为Ajax给浏览器编程带来的巨大好处,让我把几乎所有的浏览器客户端代码都改成了Ajax模式。不过,在我的Windows Xp Sp2上,总是有一定机率会出现Ajax被吊住(hang)的诡异情况。也就是说,Ajax始终处于接收Response状态,但Response始终不完成。
说这个情况诡异,是因为既不是服务器端问题,也不是浏览器端的问题。我曾经在服务器程序上加入跟踪代码,然后在浏览器反复进行Ajax调用上百次,发现无论是不是被吊住,服务器端的程序每次都好好地执行完毕。致于客户端,每次发送的内容都是一样的,每次都是顺利发出Ajax请求,但是就有那么几次,Ajax始终处于等待Response状态。
还有其他的现象,往往打开浏览器第一次Ajax访问不会吊住,后面几次有可能。Ajax的Get情况很少吊住,Post吊住机率大。有的时候,Ajax吊住频繁,高峰时会达到10次访问有3次被吊住的情形。
想到过可能是防病毒软件的问题。我使用的是Kaspersky,支持Web Anti-Virus机制,就是能够监控所有HTTP协议的网络访问,根据扫描结果判定是否拦截。暂时中止Kaspersky进行测试后发现,吊住机率大大降低。于是暂时采取锯箭法解决,在Kaspersky中将我自己的服务器Url设为Trust,问题缓解。不过,无法要求别人都这么做,也不能让别人都不用防病毒软件啊,所以这只是锯箭法。
后来再做了一些测试,由于Firefox中的Firebug插件可以监控网络访问的详细信息,对Request和Response信息进行了逐个排查,发现我的Ajax访问的Request Header和Response Header中Connection都是Keep-Alive。于是产生了莫名其妙的直觉,在代码中将这个参数设置为close,居然再也没有出现吊住的情况。
大致代码如下,假设此前已经将XMLHttpRequest弄到this._Transport里面去了,而且已经执行过open了。如果没有open而如下调用,会出现一个Exception。如果你对Ajax不了解,这段话可能显得很诡异,没关系,一旦你知道Ajax是怎么回事,就不会觉得诡异了。o:)
this._Transport.setRequestHeader("Connection", "close");现在想来,这个Ajax吊住的情形可能是Kaspersky监控http和Ajax调用混合出现的异常,加上IIS 5.1、Windows Xp Sp2这几桩事情放在一起让异常加剧。在Ajax中把Connection总是设成Close,取代原先缺省的Keep-Alive,稍微牺牲了一点网络流量,Ajax却大大稳定了。
Ajax往往会处于非常复杂的环境,浏览器软件、网络协议、服务器软件、防病毒软件、防火墙,会形成错综复杂无法穷尽的各种组合。这个Connection的设置往往会被忽略,看上去设置成close显得强壮的很。这次应该不再是锯箭法了。
波波坡原创文章 链接:http://www.bobopo.com/article/code/ajax_hang.htm
标签: Javascript
关键词: ajax, 吊住, 挂起, hang, Response Header, Request Header, 防病毒软件, Kaspersky, Anti Virus, Connection, Keep-Alive
创建日期: 2008-06-13