ajax|js
(翻譯)使用JSON加速AJAX
使用JSON加速AJAX
By Sean Kelly
當微軟在IE中添加了用於執行JavaScript的ActiveX XMLHTTP對象以後,彷彿播下了AJAX這一Web應用開發的革命的火種。如今,Firefox, Safari, Opera, 以及其他的瀏覽器都提供了XMLHttpRequest,使得他們可以訪問colr.org, backpackit.com, maps.google.com.這些網站的特點就是它們的應用程式表現和感覺和其他傳統型應用程式一樣,儘管他們運行在瀏覽器裡邊。
在AJAX裡邊,當使用者查看和與頁面互動的時候,頁面的JavaScript代碼向web伺服器請求資料(AJAX裡的“非同步”)。這些請求是HTTP請求,就像一個瀏覽器在第一個地方取得頁面,其中可以包括任意圖片,樣式表等等。同樣的,XMLHttpRequest對象也可以用來取得各種資料,不只是XML。例如,JavaScript可以使用XMLHttpRequest從web伺服器取得一個普通文字檔,並在一個表單裡邊顯示其內容。
XMLHttpRequest對象通過尋找位於資料前端的Content-type header來分析從web伺服器返回的資料的MIME類型。例如,如果類型是text/plain,你可以通過檢查XMLHttpRequest對象的responseText屬性來訪問該文本。但是,如果類型是text/xml,XMLHttpRequest對象有一個特殊的步驟:它對返回的文檔運行一個XML解析,並在記憶體中建立一個文件物件模型(DOM)樹來描述文檔,使得文檔在responseXML屬性中可用。然後,你就可以使用JavaScript的標準DOM方法來操縱這個對象樹並訪問每個元素,屬性以及樹裡的其他文本。
XML是交換資料的標準方法,但通常不是最好的方法。儘管XML可以為資料添加結構和中繼資料,但這確實是一個比較麻煩的方法。XML還有相當複雜的文法,需要一個解析器類解析它。在JavaScript中,XML必須被解析為DOM樹才可以使用。並且,一旦構建了DOM樹,你還不得不通過建立相應的JavaScript對象或其他方法才能在用戶端應用程式中使用XML資料。
幸運的是,還有更好的辦法。
使用JSON
JSON也就是JavaScript Object Notation,是一個描述資料的輕量級文法。JSON的優雅是因為它是JavaScript語言的一個子集。接下來你將看到它為什麼如此重要。首先,來比較一下JSON和XML文法。
JSON和XML都使用結構化方法描述資料。例如一個地址簿應用程式可以提供用來產生XML格式的地址卡的web服務:
Sean Kelly
SK Consulting
kelly-AT-seankelly-DOT-biz
kelly-AT-seankelly-DOT-tv
+1 214 555 1212
+1 214 555 1213
+1 214 555 1214
1234 Main St
Springfield, TX 78080-1216
5678 Main St
Springfield, TX 78080-1316
http://seankelly-DOT-biz/
http://seankelly-DOT-tv/
使用JSON, 形式如下:
{
“fullname“: “Sean Kelly”,
“org“: “SK Consulting”,
“emailaddrs”: [
{“type“: “work“, “value“: “kelly-AT-seankelly.biz”},
{“type“: “home“, “pref“: 1, “value“: “kelly-AT-seankelly.tv”}
],
“telephones”: [
{“type“: “work“, “pref“: 1, “value“: “+1 214 555 1212”},
{“type“: “fax“, “value“: “+1 214 555 1213”},
{“type“: “mobile“, “value“: “+1 214 555 1214”}
],
“addresses”: [
{“type“: “work“, “format“: “us”,
“value“: “1234 Main StnSpringfield, TX 78080-1216”},
{“type“: “home“, “format“: “us”,
“value“: “5678 Main StnSpringfield, TX 78080-1316”}
],
“urls”: [
{“type“: “work“, “value“: “http://seankelly.biz/”},
{“type“: “home“, “value“: “http://seankelly.tv/”}
]
}
如你所看到的,JSON有結構化的嵌套資料元素,這一點和XML相似。JSON也是基於文本的,XML也是如此。兩者都使用Unicode。JSON和XML都很容易閱讀。主觀上,JSON更清晰,冗餘更少。JSON WEB網站嚴格地描述了JSON文法,目前就是這樣的。它確實是一個簡單的小語言! XML確實適合標記文檔,但是JSON是資料互動的理想格式。每個JSON文檔描述了一個這樣一個對象,該對象包含有:嵌套對象、數組、字串、數字、布爾值或空值。
在這些地址卡例子代碼中,JSON版本是更輕量級的,只佔用了682位元組的空間,而XML版本需要744位元組空間。儘管這不是一個可觀的節省。而實際的好處則來自解析過程。
XML對比JSON:地位喪失
通過使用XMLHttpRequest對象,可以從你的基於AJAX的應用程式取得XML和JSON檔案。典型的,互動代碼如下:
var req = new XMLHttpRequest();
req.open(“GET“, “http://localhost/addr?cardID=32”, /*async*/true);
req.onreadystatechange = myHandler;
req.send(/*no params*/null);
作為WEB伺服器響應,你提供的處理器函數(myHandler函數)被多次調用,為你提供提前終止事務,更新進度條等機會。通常的,只有在web請求完成以後才起作用:那時,你就可以使用返回的資料了。
為了處理XML版本的地址卡資料,myHandler的代碼如下:
function myHandler() {
if (req.readyState == 4 /*complete*/) {
// Update address field in a form with first street address
var addrField = document.getElementById(‘addr‘;
var root = req.responseXML;
var addrsElem = root.getElementsByTagName(‘addresses‘[0];
var firstAddr = addrsElem.getElementsByTagName(‘address‘[0];
var addrText = fistAddr.firstChild;
var addrValue = addrText.nodeValue;
addrField.value = addrValue;
}
}
值得注意的是你不必解析XML文檔:XMLHttpRequest對象自動地解析了,並使responseXML中的DOM樹可用。通過使用responseXML屬性,可以調用getElementsByTagName方法尋找文檔的地址部分,你還可以使用第一個去找到它。然後,可以再次調用getElementsByTagName在地址部分尋找第一個地址元素。這就取得了文檔的第一個DOM子節點,就是一個文本節點,並取得節點的值,這就是你想要的街道地址。最後,可以在表單域中顯示結果。
確實不是一個簡單的工作,現在,使用JSON再試一下:
function myHandler() {
if (req.readyState == 4 /*complete*/) {
var addrField = document.getElementById(‘addr‘;
var card = eval(‘(‘ req.responseText ’)’);
addrField.value = card.addresses[0].value;
}
}
你所做的第一件事情就是解析JSON響應。但是,因為JSON是JavaScript的一個子集,你可以使用JavaScript自己的編譯器來解析它,通過調用eval函數。解析JSON僅需要一行!此外,操縱JSON中的對象就像操縱其他JavaScript對象一樣。這顯然要比通過DOM樹來操縱簡單,例如:
card.addresses[0].value 是第一個街道地址, “1234 Main Stb &”
card.addresses[0].type 是地址類型, “work”
card.addresses[1] 是家庭地址對象
card.fullname 是card的名稱, “Sean Kelly”
如果更仔細觀察,你可能會發現XML格式中文檔至少有一個跟元素,card。這在JSON裡是不存在的,為什嗎? 大概就是,如果你正在開發JavaScript來訪問Web服務,你已經知道你想要得到的。然而,你可以在JSON中這麼使用:
{“card“: {“fullname”: ...}}
使用這個技術,你的JSON檔案總是以一個帶有單一命名屬性的對象開始,該屬性標識了對象的種類。
JSON是快速可靠的嗎?
JSON提供輕量的小文檔,並且JSON在JavaScript更容易使用。XMLHttpRequest自動為你解析了XML文檔,而你還要手工解析JSON檔案,但是解析JSON比解析XML更慢嗎?作者通過幾千次的反覆測試,使用XMLHttpRequest解析XML和解析JSON,結果是解析JSON比XML要快10倍!當把AJAX當作案頭應用看待時,速度是最重要的因素,很明顯,JSON更優秀。
當然,你不能總是控制伺服器端來為AJAX程式產生資料。你還可以使用第三方伺服器代替伺服器提供XML格式的輸出。並且,如果伺服器恰好提供JSON,你可以確定你真的想使用它嗎?
代碼中值得注意的是,你將響應文本直接傳入到eval中。如果你控制著伺服器,就可以這麼做。如果不是,一個惡意伺服器可以使你的瀏覽器執行危險操作。在這樣的情況下,你最好使用寫在JavaScript中的代碼來解析JSON。幸運地,這已經有了。
說到解析,Python愛好者可能注意到JSON不只是JavaScript的子集,它還是Python的一個子集。你可以在Python中直接執行JSON,或者使用安全JSON解析代替。JSON.org網站列舉了許多常用JSON解析器。
伺服器端的JSON
到現在為止,你或許將焦點注意在運行在客戶瀏覽器中的基於AJAX的web應用程式使用JSON。自然地,首先,JSON格式的資料必須在伺服器端產生。幸運地是,建立JSON或將其他存在的資料轉換成JSON是相當簡單的。一些WEB應用程式架構,例如TurboGears,自動包括對JSON輸出的支援。
此外商業WEB服務提供者也注意到了JSON。Yahoo最近建立了許多基於JSON的web服務。Yahoo的多種搜尋服務,履行計劃,del.icio.us,還有高速公路交通服務也都支援JSON輸出。毫無疑問,其他主要WEB服務提供者也將加入到對JSON的支援中。
總結
JSON的聰明在於它是JavaScript和Python的子集,使得它更易用,為AJAX提供高效的資料互動。它解析更快,比XML更易使用。JSON正成為現在“Web 2.0”的最強音。每個開發人員,無論是標準傳統型應用程式或Web應用程式,越來越注意到了它的簡單和便捷。我希望你能體會到在buzzword-compliant, Web-2.0-based, AJAX-enabled, 敏捷開發中應用到JSON的樂趣。
關於作者
Sean Kelly 是一個希臘神話和喜劇愛好者,注意到了AJAX和JSON的潛在作用。他的AJAX團隊Argonauts打算解決在web應用開發,python,AJAX,java,web服務以及令人生厭的XML中的各種問題。他在醫學,天文學以及數位媒體工業等方面都有研究,還堅持每天都做瑜伽。他和他妻子Mary以及女兒Ariana居住在一個不為人知的地方。
<