掌握 Ajax,第 7 部分: 在请求和响应中使用 XML
| 了解什么時候適合什么時候不適合使用 XML |
級別: 中級 Brett McLaughlin (brett@oreilly.com), 作家,編輯, O'Reilly and Associates 2006 年 10 月 23 日 偶爾使用 Ajax 的開發人員也會注意到 Ajax 中的 x 并意識到它代表 XML。XML 是編程中最常用的數據格式之一,對于異步應用程序中的服務器響應能夠帶來切實的好處。在本文中,您將看到服務器如何在請求響應中發送 XML。現在如果不使用 XML 就不能進行任何有意義的編程。無論考慮轉向 XHTML 的網頁設計人員、使用 JavaScript 的 Web 程序員、使用部署描述文件和數據綁定的服務器端程序員,還是研究基于 XML 的數據庫的后端開發人員,都在使用這種可擴展標記語言。因此,XML 被認為是 Ajax 底層的核心技術之一就不足為奇了。 但是,這種觀點反映到 Ajax 應用程序就表現在其核心對象所選的名稱 —— XMLHttpRequest,這個名稱不是很好,因為它并沒有反映技術上的實際情況。換句話說,多數人之所以認為 XML 是 Ajax 的核心組成部分,僅僅是因為他們想當然地以為 XMLHttpRequest 對象在任何時候都使用 XML。但實情并非如此,本文第一部分給出了原因。實際上,您將看到在多數 Ajax 應用程序中 XML 很少出現。 XML 確實有應用在 Ajax 中,而且 XMLHttpRequest 也支持這種用法。也確實沒有什么能阻擋您向服務器發送 XML。在本系列前面的文章中,我們使用普通文本和名/值參數發送數據,但 XML 也是一種可行的格式。本文將介紹如何來這樣做。但最重要的是,我將討論為何可以使用 XML 作為請求格式,以及為何在多數情況下不應該使用它。 XML:到底用沒用? 對 Ajax 應用程序及它們使用 XML 的情況很容易犯想當然的錯誤:這種技術的名稱(Ajax)及其使用的核心對象(XMLHttpRequest)都暗示了 XML 的使用,談到 Ajax 應用程序的時候也經常聽到 XML。但是,這種觀點大錯特錯,如果希望在編寫異步應用程序時真正做到胸有成竹,必須知道這種想法是錯誤的,而且最好知道為什么錯誤。 XMLHttpRequest:糟糕的名稱和 HTTP 一項技術可能遇到的最糟的境況之一是它變得太炙手可熱以至于無法再改變它的一些基本內容。XMLHttpRequest 恰恰是這種情形,它是 Ajax 應用程序中使用的基本對象。聽起來它似乎是為通過 HTTP 請求發送 XML 或者以某種 XML 格式發出 HTTP 請求而設計的。但不論這個對象的名稱聽起來像什么,實際上它要做的只不過是為客戶機代碼(在網頁中通常是 JavaScript)提供一種發送 HTTP 請求的方式。僅此而已,別無其他。 因此,如果將 XMLHttpRequest 改成某種更準確的名稱可能更好一些,比如 HttpRequest,或者簡簡單單的 Request。但是,現在成千上萬的人在應用程序中使用了 Ajax,而且我們知道需要幾年時間(如果不是十幾年的話)大部分用戶才會改用 Internet Explorer 7.0 或 Firefox 1.5 這些新版本的瀏覽器,因此這么修改實際上是不可行的。最終我們不得不使用 XMLHttpRequest,這就要求開發人員要知道其名不符實的這一事實。 在一定程度上講,對于不支持 XMLHttpRequest 的瀏覽器(特別是在 Windows 上)的最佳回溯方法之一就是使用 Microsoft IFRAME 對象。聽起來可不像是 XML、HTTP 或請求,是不是?當然,所有這些都可能涉及到,但是這正清楚地說明了一點 —— XMLHttpRequest 對象更多的是關于在不重新加載頁面的情況發出請求,而不會太多地涉及 XML 甚至 HTTP。 請求是 HTTP 而非 XML 另一種常見的錯誤是認為 XML 在幕后使用 —— 坦白地說,我也曾這么認為!但是,持這種觀點表明您對這種技術還不甚了解。當用戶打開瀏覽器從服務器上請求網頁時,會輸入 http://www.google.com 或者 http://www.headfirstlabs.com 這樣的東西。即便不輸入 http://,瀏覽器也會在地址欄的這部分加上。第一部分,即 http://,是關于如何通信的很直觀的線索:通過超文本傳輸協議 HTTP。在網頁中編寫代碼與服務器通信時,無論使用 Ajax 還是普通的表單 POST,甚至超鏈接,打交道的都是 HTTP。
既然瀏覽器和服務器之間的所有 Web 通信都通過 HTTP 進行,認為 XML 是 XMLHttpRequest 幕后所用的某種傳輸技術的想法就毫無道理了。當然在 HTTP 請求中可以發送 XML,但是 HTTP 是一個精確定義的協議,短時間內不可能消失。除了在請求中明確使用 XML,或者服務器用 XML 發送響應之外,XMLHttpRequest 對象使用的只是普普通通的 HTTP。因此,當再有人對您說 “哦,稱為 XMLHttpRequest 是因為在幕后使用 XML” 的時候,您最好一笑了之,并耐心地解釋什么是 HTTP,告訴他們雖然 XML 可以通過 HTTP 發送,但 XML 是一種數據格式而不是傳輸協議。通過這樣的討論,加深對它的理解。
使用 XML(真正) 到目前為止,我說的只是 Ajax 在哪些地方不使用 XML。但 Ajax 中的 x 和 XMLHttpRequest 中的 XML 仍然有其實際意義,在 Web 應用程序中使用 XML 有多種選擇。這一節將討論基本的選擇,剩下的部分再深入探討細節問題。 XML 選項 在異步應用程序中 XML 有兩種基本的用法:
其中第一種用法,即用 XML 發送請求,需要將請求的格式設置為 XML,可以使用 API 來完成,也可以與文本連成字符串,然后將結果發送到服務器。按照這種思路,主要的任務就是通過既符合 XML 規則又能被服務器理解的方式構造請求。因此這里的關鍵實際上是 XML 格式,得到需要發送的數據之后,只需要用 XML 語法將其包裝起來。本文后面討論 XML 在 Ajax 應用程序中的這種用法。 第二種用法,即用 XML 接收請求,需要從服務器上接收響應,然后從 XML 提取數據(同樣,可以用 API 或者采用蠻力方法)。這種情況下,關鍵在于來自服務器的數據,而您恰好需要從 XML 中提取這些數據以便使用。這是本系列下一期文章的主題,到那時候我們再詳加討論。 一點忠告 再詳細討論使用 XML 的細節之前,首先給您一句忠告:XML 不是一種簡潔、快速和節省空間的格式。在后面幾節以及本系列的下一期文章中將看到,在上下文中使用 XML 確實有一些很好的理由,XML 與普通文本的請求和響應(特別是響應)相比也確實有一些長處。但是,和普通文本相比,XML 通常總會占用更多的空間,速度也更慢,因為需要在消息中增加 XML 所需要的標簽和語義。 如果需要編寫速度很快、看起來像桌面應用的程序,XML 可能不是最佳選擇。如果從普通文本開始,然后發現確實需要 XML,那么就使用它;但是如果從一開始就使用 XML,基本上可以肯定一定會降低應用程序的響應性。多數情況下,與將文本轉化成下面這種 XML 相比,發送普通文本會更快一些(使用類似 name=jennifer 的名/值對):
看看哪些地方使 XML 增加了處理時間:將文本包裝成 XML;發送額外信息(要注意我沒有包含任何包圍元素、XML 頭或者可能出現在實際請求中的其他任何內容);讓服務器解析 XML、生成響應、用 XML 包裝響應,并將它發送回網頁;讓網頁解析響應,最后使用它。因此要清楚什么時候使用 XML,不要一開始就認為它在很多情況下都能夠加快應用程序;但,它可以增強靈活性,這就是我們現在要討論的。
從客戶機到服務器的 XML 我們來看看將 XML 作為從客戶機向服務器發送數據的格式。我們首先討論技術上的實現,然后花些時間分析什么時候適合什么時候不適合使用它。 發送名/值對 在您編寫的 90% Web 應用程序中,最終都會使用名/值對發送到服務器。比方說,如果用戶在網頁表單中輸入姓名和地址,可能希望數據采用下列形式:
如果使用普通文本把這些數據發送到服務器,可以使用清單 1 所示的代碼。類似于本系列第一期文章中使用的那個例子。請參閱參考資料。 清單 1. 使用普通文本發送名/值對
將名/值對轉化成 XML 如果希望這樣使用 XML 作為數據格式,首先要做的是找到一種基本 XML 格式來存儲數據。顯然,名/值對可以全部轉化成 XML 元素,以其中的名稱作為元素名,值作為元素的內容:
當然,XML 要求有一個根元素;如果使用文檔片段(XML 文檔的一部分)的話則需要一個封閉元素。因此可能需要將上述 XML 轉化成下面的形式:
現在基本上可以準備在 Web 客戶機上創建這種結構并發送到服務器了。 通信,口頭上的 在網絡上傳輸 XML 之前,需要保證服務器以及發送數據的腳本能夠接受 XML。現在對很多人來說這么強調似乎有點多余,認為這是理所當然的,但是很多新手往往認為只要通過網絡發送 XML,就能夠被正確地接收和解釋。 實際上,需要兩個步驟來保證發送的 XML 的數據能夠被正確地接收: 這兩方面都可能要求您進行人際溝通,必須明確地告知對方!嚴格地說,如果確實需要發送 XML 數據,多數腳本作者都會幫助您,因此尋找能夠接受 XML 的腳本應該不難。但是,仍然需要保證格式是腳本所希望的格式。比方說,假設服務器接受下列格式的數據:
看起來和上面的 XML 類似,只有兩點不同: 從大的層面上來說,這些小問題僅僅是服務器接收和處理數據的區別,但是服務器會徹底失敗,在網頁上(可能向其用戶)顯示意義含糊的錯誤消息。因此必須明確服務器的期望的格式,并把要發送的數據塞進那種格式。然后,只有在這時才會涉及到從客戶機向服務器發送 XML 數據的真正的技術問題。 向服務器發送 XML 當向服務器發送 XML 的時候,更多的代碼用于獲取數據和包裝成 XML,而不是真正的傳輸數據。實際上,只要準備好發送到服務器的 XML 字符串,發送工作就和普通文本一樣了,如清單 2 所示。 清單 2. 用 XML 發送名/值對
大部分代碼都很簡單,只有少數地方值得提一下。首先,請求中的數據必須手工格式化為 XML。閱讀了三篇關于使用文檔對象類型的文章之后,再來討論它是不是很簡單了?雖然不禁止在 JavaScript 中使用 DOM 創建 XML 文檔,但是在通過 GET 或 POST 請求發送到網絡上之前必須將 DOM 對象轉化成文本。因此使用常規字符串操作來格式化數據更簡單一些。當然,這樣很容易出現錯誤和誤輸入,因此在編寫處理 XML 的代碼時必須非常小心。 建立 XML 之后,按照和發送文本基本相同的方式打開連接。對于 XML 最好使用 POST 請求,因為有些瀏覽器限制了 GET 請求字符串的長度,而 XML 可能很長,可以看到清單 2 中把 GET 改成了 POST 方法。此外,XML 通過 send() 方法發送,而不是附加在請求 URL 最后的參數。這些都是非常細微的區別,很容易修改。 但是必須編寫一行新的代碼:
看起來很難理解,它只不過是告訴服務器要發送的是 XML 而不是一般的名/值對。無論哪種情況,發送的數據都是文本,但這里使用 text/xml 或者 XML 作為普通文本發送。如果使用名/值對,對應的行應該是:
如果忘記告訴服務器發送的是 XML,就會出現問題,因此不要忘掉這一步驟。 完成這些之后,剩下的就是調用 send() 并傳入 XML 字符串了。服務器將收到您的 XML 請求,并(假設已經做好了準備工作)接受 XML,解釋它,然后返回響應。實際上要做的只有這么多 —— XML 請求只需要稍微修改代碼。
發送 XML:好還是不好? 在結束 XML 響應的 XML 請求(以及本文)之前,我們花點時間討論一下在請求中使用 XML 的感受。前面已經提到,就傳輸而言 XML 完全不是最快的方式,但是還有更多因素要考慮。 構造 XML 不是簡單的事情 首先必須認識到,對于請求來說構造 XML 不是簡單的事。如清單 2 所示,數據很快就會和 XML 語義糾纏在一起:
似乎還不壞,但是要知道這是只有六個字段的 XML 片段。開發的多數 Web 表單都有十到十五個字段,雖然不一定所有的請求都使用 Ajax,但是應該考慮這種情況。至少要花和實際數據同樣多的時間來處理尖括號和標簽名稱,有可能使本來很少的輸入變得非常大。 這里的另一個問題前面已經提到,即必須手工創建 XML。使用 DOM 不是一種好的選擇,因為沒有簡單易行的辦法將 DOM 對象轉化成在請求中發送的字符串。因此像這樣使用字符串處理是最好的辦法,不過也是一種維護起來最困難和新開發人員最難理解的方法。在這個例子中,所有 XML 都在一行中構造完成,如果分為多步只會更加混亂。 XML 沒有為請求增加任何東西 除了復雜性的問題之外,和普通文本以及名/值對相比,在請求中使用 XML 實際上沒有多少好處(如果有的話)。要注意,本文堅持使用前面用名/值對發送的同一些數據(請參閱清單 1)來用 XML 發送。我沒有提什么數據能用 XML 但是不能用普通文本發送,這是因為實際上沒有任何東西可用 XML 而不能用普通文本發送。 事實上這就是 XML 和請求的底線:不是一定非要這么做不可。在本系列的下一期文章中將看到服務器可以使用 XML 實現普通文本很難做到的一些事情,但請求不屬于這種情況。因此除非和只接受 XML 的腳本(確實存在這樣的腳本)打交道,在請求中最好使用普通文本。
結束語 通過本文,您現在可能已經開始對 Ajax 中的 XML 有一些更深的理解了。您知道 Ajax 應用程序不一定要使用 XML,XML 也不是數據傳輸中的什么法寶。還知道從網頁向服務器發送 XML 不是多么難的事情。更重要的是,您知道為了確保服務器能夠處理和響應請求需要做什么:必須保證服務器腳本接受 XML,而且能夠識別用于發送數據的格式。 您還應該非常清楚 XML 對于請求來說并不一定是很好的數據格式。在以后的文章中,您將看到 XML 在某些情況下是有利的,但在多數請求中,它只會降低速度和增加復雜性。因此雖然通常我都會建議您馬上應用在文章中學到的內容,但是對本文來說,我建議您在應用這里學到的知識時最好三思而后行。XML 請求在 Ajax 應用程序中有自己的價值,但是并不像您所想象的那么大。 在下一期文章中,我們將討論服務器如何使用 XML 做出響應,以及 Web 應用程序如何處理這些響應。令人高興的是,服務器能夠將 XML 發送回 Web 應用程序,這樣做的理由比較充分,因此那篇文章中的技術細節更實用,目前您只需要知道 XML 為何并非一定是最佳選擇 —— 至少對發送請求而言。您可以嘗試使用 XML 作為請求數據格式實現某些 Web 應用程序,然后再換回普通文本,看看哪種辦法更快更簡單。下一期文章再見。 參考資料 學習
|
轉載于:https://www.cnblogs.com/China-Dragon/archive/2010/05/07/1730142.html
總結
以上是生活随笔為你收集整理的掌握 Ajax,第 7 部分: 在请求和响应中使用 XML的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 注册MSComm方法
- 下一篇: c#中获取服务器IP,客户端IP以及其它