利用原來的文章: http://diary.tw/tim/18 撰寫了一個更容易測試的 html 範例, 一則以測試同步及非同步, 另一則了解在IE及FF的 AJAX Callback 的差異.
1. browser cache:
在做 AJAX Callback 時, 若是 server side 程式不強迫 client side browser 不 cache 時, IE 會發生 callback response cache 的行為, 這個會讓 AJAX 取得的回應發生問題, 當然有多重方法可以解決, 在 FF 就沒有這種現象. 比較單純而又通用解決方法就是在 callback url 上動手腳, 和一般解決 cache 的方法相同, 這裡利用了 javascript 的時間戳記來將 url 變成每次都不同. 一般的實作方法有兩個, 一個是用 Date.parse(new Date()) 方法, 但時間比較不精確(每次取回的值最後三位皆為 000, IE, FF皆同), 另一則是 (new Date()).getTime() 似乎比較精確, 這兩個方法都是傳回從 January 1, 1970, 00:00:00, local time 開始的 milliseconds. 當然, server side 加不加上 cache control 的 header 就比較不影響了, 因為每次 browser 就會乖乖地來 request.
2. callback handler 的放置位置:
非同步呼叫時, 要給定 callback handler function, 由於是跨 function 的呼叫, 若是要寫 generic 一點, 就得將 XMLHttpRequest 物件變數往上一層放, 讓呼叫時, 非同步處理函數仍能取得 XMLHttpRequest 變數進行回應後的處理. 同步呼叫時就沒這個問題, 不過 browser UI 上的使用者經驗就會比較差一點. 另外非同步呼叫時, 最好能放一個動畫, 讓使用者覺得是在處理中.
3. 非同步呼叫的重覆操作行為:
由於同步呼叫時, 無論 IE 或 FF 全頁面都會進行等待的狀態, 所以使用者不會有重覆操作 UI 的問題, 但是非同步呼叫時, 使用者是可以再次操作 UI 上的任何元件. 這個測試是利用非同步呼叫, 連續按兩次後的狀況. FF 在發生時, 第二次的 send 會發生 exception, 而造成兩次的非同步呼叫都沒有回傳給 handler, 當然, 若是先按非同步再按同步呼叫時, 一樣第二次也有 exception, 而且也都沒有回應. 透過sniffer或ethereal來觀察時, 也發現 server 第一次呼叫並無回應正常的200, 而
第二次根本也無發出 request 的現象. (應該是第二次呼叫是會先 cancel 第一次呼叫的 reqeust, 所以 server 也就不 response 了)
再來看看 IE 的表現囉, 重覆執行時(無論是兩次非同步呼叫或是第一次非同步, 第二次同步呼叫, 第二次 always 是可以正常工作的, 當然, 第一次仍舊不會有任何結果(sniffer 或 ethereal 也看不到回應, 而第二次仍舊會發出 request), 這個行為似乎比較理想. 但無論如何, 應該要避免使用者重覆去操作這類行為, 以免造成不必要的問題. (特別為此測試在 server sied 將 client 傳回的 t=? 的內容 response 回來, 以方便確認回傳的資料是回應哪次的呼叫.
4. session 及 cookie 皆共用:
這個部分在 IE 及 FF 皆沒有太大問題, 有了這個特性, 才方便做安全性的檢查, 不致有麻煩的使用者身份確認的問題.
5. http_referer client header問題:
這個也十分有趣, IE 會帶回原 callback 的呼叫頁參考來源 url , 但 FF 並不會做這件事, 當然, 就變成要利用這個 client header 來辨識使用者從哪裡來就比較麻煩了. 不過也可以利用 XMLHttpRequest 的 setRequestHeader 方法來自行設定 referer, 語法如下:
obj.setRequestHeader('Referer', document.location.href);
有可能是 IE 是起 activex object, 而 FF 是起內建的 XMLHttpRequest object 才會行為有所不同.
6. 另外一個奇怪的顯示, FireBug 是一個很不錯的 client side javascript 除錯器(詳見:
http://diary.tw/tim/7), 而且也有完成的 AJAX Callback 記錄, 以方便除錯. 但若故意在呼叫 XMLHttpRequest send 方法時, 即使使用 GET 方法, 但 FireBug 的 debug UI 上仍會呈現 POST 的內容, 但實際上並不會傳出 (可由 sniffer 或 ethereal 等軟體觀察), 這是要注意不要被誤導的畫面混淆了. (這個測試很無聊吧!! 明明就是 HTTP GET, 就硬要在 send 中加資料, 不過 IE 和 FF 表現都很正常, 不會理這個 send 中的資料)
附件為一個 ajax.htm 配合 test.php (server side) 的範例, 本文測試皆以這個範例程式為準, FF 為 1.5.0.6 (Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.0.6) Gecko/20060728 Firefox/1.5.0.6), IE 為 6.0.2900.2180.xpsp_sp2_gdr.050301-1519 , 若有興趣, 可以自行下載研究, 並歡迎心得分享.
實測用網址:
http://sample.diary.tw/1/ajax.htm