天天看點

請慎用Ajax請求來探測不存在的資源

請慎用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,但是也有一些變與不變的因素。一般來講,人們在實作一個通用的功能時,都會将成功的一面做的特别好,比較一緻,而将錯誤處理個性化起來,特别是一個新生事物,成功的一面通過大家的使用,都會統一起來,而錯誤處理由于較少有人碰到,結果導緻形态各異。在具體進行設計時,一定要對以來的條件因素進行區分,慎選。如果依賴于一些變化快速的因素,将導緻設計失敗。特别考慮那些易變的部分,比如錯誤處理,在前期研究時就要投入更多精力。前期研究時,也應當特别考慮極端情況,進而提高研究的價值,降低風險。