翻 譯:www.ruby-china.cn 站長]
Prototype框架提供了非常容易和有意思的方法處理Ajax的調用,同時它也是瀏 覽器安全的 。除了簡單的請求外,這個模塊(指prototype里的Ajax)也能很聰明的處理從服務器返回 的javascript代碼,并且提供了一個輔助的類不停的輪循。
Ajax的功能包含在了全局的Ajax對象里面。用于Ajax請求的 transport是xmlHttpRequest,它是從用戶角度的對不同瀏覽器進行安全的抽象的結果。真正的請求是通過創建Ajax. Request對象的實例實現的。復制內容到剪貼板代碼: new Ajax.Request('/some_url', { method:'get' });第一個參數是請求的地址,第二個是可選的哈希值。方法選項指定要使用的HTTP請求方法,默認是POST。
記住,由于安全的原 因(也就是防止跨站腳本攻擊)Ajax請求只能被用在與包含這個Ajax請求頁面相同的協議、主機與端口上。有些瀏覽器會允許任意的URL,但是你能不依 靠這個。
Ajax響應回調
Ajax請求默認是異步的,這也就意味著你必須要有回調函數能夠處理返回的數據。回調方法 在發起請求的時候傳給可選的哈希。復制內容到剪貼板代碼:
new Ajax.Request('/some_url',這里兩個回調函數傳給了這個哈希值,分別表示成功與失敗的警告。onSuccess和 onFailure根據返回的狀態相應的被調用。第一個參數是原生的xmlHttpRequest對象,可以分別使用它的responseText和 responseXML屬性。
{
method:'get',
onSuccess: function(transport){
var response = transport.responseText || "no response text";
alert("Success! \n\n" + response);
},
onFailure: function(){ alert('Something went wrong...') }
});
你可以把兩個回調都定義,也可以是一個或者沒有,這全由你來定。其它的可以用的回調函數還有:
onUninitialized,
onLoading,
onLoaded,
onInteractive,
onComplete and
onException.
他們都與xmlHttpRequest的傳輸的某一個狀態有關系,除了在分發其它回調時出現異常后引起的onException外。
還 有可以得到的就是onXXX的回調。這里XXX是HTTP的返回狀態,象200或者404。需要注意的是,如果用這種方法,你的onSuccess和 onFailure就不會被調用了。因為onXXX有更高的優先級,因為這樣做的話,表示你知道你在做什么。
而 onUninitialized、onLoading、 onLoaded和onInteractive這些回調函數并沒有完全的被所有的瀏覽器實現出來。通過我們避免使用它們。
參數與 HTTP方法
你可以將請求參數象一個參數屬性一樣傳遞。復制內容到剪貼板代碼:
new Ajax.Request('/some_url', {
method: 'get',
parameters: {company: 'example', limit: 12}
});那么參數會以company=example&limit=12的形式發出。
你可以使用GET/POST中的任一種。但是需要注意的是GET的請求不應該導到致數據發生變化
。瀏覽器很少會緩存POST請求,但是它往往會緩存GET請求。
參數屬性的一個重要的應用是用Ajax請求發送一個FORM的內容,Prototype已經給了你一個
幫助的方法,叫做Form.serialize:復制內容到剪貼板代碼:
new Ajax.Request('/some_url', {
parameters: $('id_of_form_element').serialize(true)
});如果你需要發送自定義的HTTP請求頭,你可以用requestHeaders項來實現。只要作為
一個哈希或者用一個扁平的數組傳入名字—值對就可以了。如:['X-Custom-1', 'value',
'X-Custom-2', 'other value'].
如果由于某種原因,你必須POST一個自定義的POST體(沒有參數來自于參數項)的請求,有
一個postBody項就是為了這個目的設的。要注意的時,如果你使用postBody,那么你傳進來
的所有的參數都不會被發送,因為postBody有更高的優先級。這樣做的時候,你應該是清醒
的。
對javascript返回值求值
有時應用程序發送javascript代碼作為響應。如果這個返回的Contenty-Type與Javascript
的MIME的類型是一樣的,那么Prototype將會自動eval()返回的代碼。你如果沒有需要的話
,就不用顯式的處理這個響應。
還有可能就是這個響應是一個X-JSON的頭,那他的內容就會被解析,保存成立個對象并發送
給這些回調函數,當成第二個參數:復制內容到剪貼板代碼:
new Ajax.Request('/some_url', { method:'get',
onSuccess: function(transport, json){
alert(json ? Object.inspect(json) : "no JSON object");
}
});可以用這個函數來取比較重要的數據,以避免解析XML返回的損耗。JSON比XML要更快
(當然也更輕)。
全局響應者
這里有一個對象在每次Ajax請求時都會被調用:Ajax.Responders。你可以用他來注冊回調
函數在任何一個Ajax.Request狀態發生時被觸發:復制內容到剪貼板代碼:
Ajax.Responders.register({
onCreate: function(){
alert('a request has been initialized!');
},
onComplete: function(){
alert('a request completed');
}
});每個與xmlHttpRequest的傳輸狀態匹配的回調都可以放在這里,再帶上一個onCreate。
象這樣的全局的跟蹤請求在不少方面是很有用的:你可以把它們記錄下來以用于調試或者拋
出一個異常處理,來通過用戶可能的連接問題。
用Ajax.Updater來動態更新你的頁面
開發者經常想通過Ajax請求來接收HTML的片段來更新文檔的部分內容。通過Ajax.Request的
onComplete回調是相當容易的,但是如果是用Ajax.Update就會變得更加容易。
假設你的HTML文檔中有以下代碼:復制內容到剪貼板代碼:
<h2>Our fantastic products</h2>
<div id="products">(fetching product list ...)</div>'products'容器是空的,你
想把Ajax的響應的HTML返回值放到這里。沒有問題:復制內容到剪貼板代碼:
new Ajax.Updater('products', '/some_url', { method: 'get' });這就是全部,沒有別
的其它工作。變量與Ajax.Request是一樣的。除了第一個位置上多了一個接收元素。
Prototype會通過Element.update()來神奇的把響應更新到容器。
如果你的HTML里還有內含的一些腳本,默認情況下會被過濾掉,為了讓你的腳本被執行,你
必須在evalScripts選項上傳入真值。
那如果有錯誤發生,服務器返回一個錯誤信息而不是HTML,那會怎么樣?一般來講,你不會
想插入錯誤到用戶需要內容的地方。幸運的時,prototype提供了一個方法的解決辦法:你
現在在第一個參數里傳入以這種形式{ success:'products', failure:'errors' }表示兩個
不同的容器的哈希值,而不只是原來那一個。那么成功的話,內容就會被放在success的容
器上,錯誤就會被放在failure容器上。通過使用這些特性,你的界面就會變得更加用戶友
好。
你也可能不想覆蓋當前容器中的內容,而是想把新的HTML加在最前或者最后面。很好,你完
全可以這樣做。只要把要插入的對象當成是插入參數傳遞給Ajax就可以了:復制內容到剪貼
板代碼:
new Ajax.Updater('products', '/some_url', {
method: 'get',
insertion: Insertion.Top
});Ajax.Updater就會使用給定的對象在容器('products')元素里對返回的HTML執行插入
。漂亮的手法!
用Ajax.PeriodicalUpdater自動執行請求
你發現Ajax.Updater很酷,但是你還想定時的執行他從服務器取數據?Prototype框架也有
這個東西。這個東西就是Ajax.PeriodicalUpdater,它基本上就是定時的運行Ajax.
Updater。復制內容到剪貼板代碼:
new Ajax.PeriodicalUpdater('products', '/some_url',
{
method: 'get',
insertion: Insertion.Top,
frequency: 1,
decay: 2
});兩個新的參數是頻率與衰退。頻率就是請求產生的間隔,用秒表示。這里它是1秒,表
示Ajax每分鐘請求一次。默認的頻率是2秒。我們的用戶可能會對應用有這么好的響應程序
感到非常高興,但是我們的服務器可能性會承受非常大的壓力,如果用戶一直長時間開著瀏
覽器的話。這也是為什么有decay這個選項的原因。這是一個因子,通過它,頻率會在每次
得到相同的返回內容時被加倍。第一次可能是1秒,然后是2秒,然后是4秒,然后是8這樣一
直下去。當然,如果這個服務器一直返回不同的數據,decay就不會起作用。這個因子只在
你的內容基本上不變化了,返回的數據也基本相同時才起作用。
將頻率調低可以明顯減輕服務器的負擔,因為無用的請求次數會減少。你可以用這個因子在
監視服務器的負載,或者你可以傳進1來完全關掉它(1是默認值)或者省略掉。