请慎用
Ajax
请求来探测不存在的资源
引
不知道各位有几个还记得
Apress
的《
Foundations.of.Ajax
》中描述的
HEAD
请求的
pattern
?
是的,你可以利用
XHR
向一个你并不知道在与不在的资源发送请求,从而探测期的存在,做出相应的判断处理。其实发送任何
GET
请求也可以,只不过一般认为
HEAD
请求比较轻量级,比较容易使用而已。
但实际上是这样子吗?
案例
在技术上我是比较激进的一派,还保持着热血青年的特性。所以,在当时新需求到来时,为了印证新技术的可行性,我冒险采用了
XHR
的
HEAD
方式。
需求是这样的:
我们需要及时探知远程服务器的状态,从而做到在服务器状态发生变化时(比如,机器刚刚启动起来),通知客户端的用户。
在以前,这样的需求你是无法用
Web
实现的。顶多你用一个
Web
服务器上的服务端程序去探知,然后发送给
Web
客户端。但是,
Ajax
的到来让这个变为可能。通过领会
Ajax
的思想,我们果断的设计了一种方案,用
JavaScript
在客户端建立了一个应用程序,发送
XHR
请求来探知远端服务器的状态,完成相应的操作。
可以说,这样一个设计深谙
Ajax
的精髓。
XHR
的进入,让传统的
B/S
程序有向
C/S
演变的趋势。该设计迎合这种趋势,结合需求,实现了这种功能。
问题
随着测试的进行,问题接踵而至。
其实,在刚开始设计此系统时并不是没有做探索性研究。由于
Ajax
本身就是一项新技术,即便是其是新瓶装旧酒,但由于项目之前没有采用过,任何人都不会贸然采用。
不过,由于研究匆忙,测试时并没有覆盖到所有的
case
,导致问题的产生。
当该设计应用到实际的项目中去后,随着测试的开展,逐渐发现了问题。
首先,在
mozill
a
1.2.1
环境下发现该程序毫无相应。主要表现为该程序其他功能都可以运行,唯独
XHR
探测远程资源的功能无法使用。为啥呢?
经过调查,发现问题是这样的。
Mozilla
低版本浏览器确实支持
XHR
,而且之前我们也有成功的经验。可问题是
Mozilla
低版本浏览器对
XHR
的支持在请求不存在资源时有些特殊,具体表现如下。
当请求不成功时,mozill
a 1.2.1
得请求顺序如下:
1
、
READY_STATE_LOADING=1;
2
、
READY_STATE_LOADING=1;
3
、
READY_STATE_LOADED=2;
之后就销声匿迹了。
相反,我们的程序一直在等待READY_STATE_COMPLETE=4;的状态,所以程序从此失去相应。
从逻辑上讲,我们不可以依赖
READY_STATE_LOADED
状态。因为在正常时,
READY_STATE_LOADED
也是有可能出现的。所以,对
Mozilla
低版本浏览器中所存在的这种问题,我们没有太好的办法,唯一的办法就是自己设置超时机制。
之后,随着测试的深入,又发现了问题。
仅仅以
firefox
1.5.0
.4
为例来讲,其用
XHR
探测远端不存在资源的流程也是不一样的。我们发现,
win
下的
firefox
工作正常,而
linux
下的
firefox
工作起来非常缓慢。经过测试,我们发现在
linux
下的
firefox
环境中,如果要向一个远端不存在资源发送一个请求,其大约要
400
秒左右才会有返回,而同样的操作在
win
版的
firefox
上却只要几十秒而已。
仅仅时间上长短的不同,就让我们的应用方案面目皆非。
如果说
mozilla
低版本浏览器由于时间较早,其错误处理流程有问题还情有可原。但是,同样版本的
firefox
在不同的平台下表现迥异就让人太不理解了。不过没办法,项目要求必须兼容不同平台的浏览器,也必须兼容
mozilla
,所以。。。。。。
顺带替一句,
IE
的
XHR
无论何种操作均表现正常,可以依赖。而开源新贵
seamonkey
的表现同他的老大哥
firefox
一样,平台差异很大。
当然,有些程序只要求在某某平台,某某浏览器上实现,那另说。
总结
第一个吃螃蟹的总是会面临风险。成功了,人人歌颂;失败了,尽管沮丧,但是我们也不能放弃一次学习的机会。
总结如下:
依赖于不变的因素,切莫依赖于变化。在进行
OOD
时,我们通常会谈到两个原则,即开闭原则和
Liskov
原则。其实这两个原则结合起来,就是强调,要面向接口变成。因为接口一般来说都是不变的,而内部的实现是经常变化的。在这里,我们虽然不是
OOD
,但是也有一些变与不变的因素。一般来讲,人们在实现一个通用的功能时,都会将成功的一面做的特别好,比较一致,而将错误处理个性化起来,特别是一个新生事物,成功的一面通过大家的使用,都会统一起来,而错误处理由于较少有人碰到,结果导致形态各异。在具体进行设计时,一定要对以来的条件因素进行区分,慎选。如果依赖于一些变化快速的因素,将导致设计失败。特别考虑那些易变的部分,比如错误处理,在前期研究时就要投入更多精力。前期研究时,也应当特别考虑极端情况,从而提高研究的价值,降低风险。