Ajax學習(3)---在請求和響應中使用 XML(1)

XML 是編程中最常用的數據格式之一,對於異步應用程序中的服務器響應能夠帶來切實的好處。在Ajax中也不例外。

Ajax 應用程序就表現在其核心對象所選的名稱 —— XMLHttpRequest,這個名稱不是很好,因爲它並沒有反映技術上的實際情況。換句話說,多數人之所以認爲 XML 是 Ajax 的核心組成部分,僅僅是因爲他們想當然地以爲 XMLHttpRequest 對象在任何時候都使用 XML。但實情並非如此,本文第一部分給出了原因。實際上,您將看到在多數 Ajax 應用程序中 XML 很少出現。 XML 確實有應用在 Ajax 中,而且 XMLHttpRequest 也支持這種用法。也確實沒有什麼能阻擋您向服務器發送 XML。

XML在Ajax中的使用

在異步應用程序中 XML 有兩種基本的用法:

1.以 XML 格式從網頁向服務器發送請求

2.以 XML 格式在網頁中從服務器接收請求

其中第一種用法,即用 XML 發送請求,需要將請求的格式設置爲 XML,可以使用 API 來完成,也可以與文本連成字符串,然後將結果發送到服務器。按照這種思路,主要的任務就是通過既符合 XML 規則又能被服務器理解的方式構造請求。因此這裏的關鍵實際上是 XML 格式,得到需要發送的數據之後,只需要用 XML 語法將其包裝起來。本文後面討論 XML 在 Ajax 應用程序中的這種用法。

第二種用法,即用 XML 接收請求,需要從服務器上接收響應,然後從 XML 提取數據(同樣,可以用 API 或者採用蠻力方法)。這種情況下,關鍵在於來自服務器的數據,而您恰好需要從 XML 中提取這些數據以便使用。

客戶機到服務器的 XML

在您編寫的 90% Web 應用程序中,最終都會使用名/值對發送到服務器。比方說,如果用戶在網頁表單中輸入姓名和地址,可能希望數據採用下列形式:

firstName=Larry
lastName=Gullahorn
street=9018 Heatherhorn Drive
city=Rowlett
state=Texas
zipCode=75080



清單 1. 使用普通文本發送名/值對

function callServer() {
// Get the city and state from the Web form
var firstName = document.getElementById("firstName").value;
var lastName = document.getElementById("lastName").value;
var street = document.getElementById("street").value;
var city = document.getElementById("city").value;
var state = document.getElementById("state").value;
var zipCode = document.getElementById("zipCode").value;
// Build the URL to connect to
var url = "/scripts/saveAddress.php?firstName=" + escape(firstName) +
"&lastName=" + escape(lastName) + "&street=" + escape(street) +
"&city=" + escape(city) + "&state=" + escape(state) +
"&zipCode=" + escape(zipCode);
// Open a connection to the server
xmlHttp.open("GET", url, true);
// Set up a function for the server to run when it's done
xmlHttp.onreadystatechange = confirmUpdate;
// Send the request
xmlHttp.send(null);
}



將名/值對轉化成 XML

如果希望這樣使用 XML 作爲數據格式,首先要做的是找到一種基本 XML 格式來存儲數據。顯然,名/值對可以全部轉化成 XML 元素,以其中的名稱作爲元素名,值作爲元素的內容:

<firstName>Larry</firstName>
<lastName>Gullahorn</lastName>
<street>9018 Heatherhorn Drive</street>
<city>Rowlett</city>
<state>Texas</state>
<zipCode>75080</zipCode>


當然,XML 要求有一個根元素;如果使用文檔片段(XML 文檔的一部分)的話則需要一個封閉元素。因此可能需要將上述 XML 轉化成下面的形式:

<address>
<firstName>Larry</firstName>
<lastName>Gullahorn</lastName>
<street>9018 Heatherhorn Drive</street>
<city>Rowlett</city>
<state>Texas</state>
<zipCode>75080</zipCode>
</address>


現在基本上可以準備在 Web 客戶機上創建這種結構併發送到服務器了。

通信:

在網絡上傳輸 XML 之前,需要保證服務器以及發送數據的腳本能夠接受 XML。現在對很多人來說這麼強調似乎有點多餘,認爲這是理所當然的,但是很多新手往往認爲只要通過網絡發送 XML,就能夠被正確地接收和解釋。實際上,需要兩個步驟來保證發送的 XML 的數據能夠被正確地接收:

1.保證向其發送 XML 的腳本能夠接受 XML 數據格式。

2.保證腳本認可發送數據所採用的特定 XML 格式和結構。

這兩方面都可能要求您進行人際溝通,必須明確地告知對方!嚴格地說,如果確實需要發送 XML 數據,多數腳本作者都會幫助您,因此尋找能夠接受 XML 的腳本應該不難。但是,仍然需要保證格式是腳本所希望的格式。比方說,假設服務器接受下列格式的數據:

<profile>
<firstName>Larry</firstName>
<lastName>Gullahorn</lastName>
<street>9018 Heatherhorn Drive</street>
<city>Rowlett</city>
<state>Texas</state>
<zip-code>75080</zip-code>
</profile>


看起來和上面的 XML 類似,只有兩點不同:

1. 來自客戶機的 XML 封裝在 address 元素,但是服務器要求數據封裝在 profile 元素中。
2. 來自客戶機的 XML 使用了 zipCode 元素,而服務器希望郵政編碼放在 zip-code 元素中。

從大的層面上來說,這些小問題僅僅是服務器接收和處理數據的區別,但是服務器會徹底失敗,在網頁上(可能向其用戶)顯示意義含糊的錯誤消息。因此必須明確服務器的期望的格式,並把要發送的數據塞進那種格式。然後,只有在這時纔會涉及到從客戶機向服務器發送 XML 數據的真正的技術問題。

向服務器發送 XML

當向服務器發送 XML 的時候,更多的代碼用於獲取數據和包裝成 XML,而不是真正的傳輸數據。實際上,只要準備好發送到服務器的 XML 字符串,發送工作就和普通文本一樣。用 XML 發送名/值對:

function callServer() {
// Get the city and state from the Web form
var firstName = document.getElementById("firstName").value;
var lastName = document.getElementById("lastName").value;
var street = document.getElementById("street").value;
var city = document.getElementById("city").value;
var state = document.getElementById("state").value;
var zipCode = document.getElementById("zipCode").value;
var xmlString = "<profile>" +
" <firstName>" + escape(firstName) + "</firstName>" +
" <lastName>" + escape(lastName) + "</lastName>" +
" <street>" + escape(street) + "</street>" +
" <city>" + escape(city) + "</city>" +
" <state>" + escape(state) + "</state>" +
" <zip-code>" + escape(zipCode) + "</zip-code>" +
"</profile>";
// Build the URL to connect to
var url = "/scripts/saveAddress.aspx";
// Open a connection to the server
xmlHttp.open("POST", url, true);
// Tell the server you're sending it XML
xmlHttp.setRequestHeader("Content-Type", "text/xml");
// Set up a function for the server to run when it's done
xmlHttp.onreadystatechange = confirmUpdate;
// Send the request
xmlHttp.send(xmlString);
}


大部分代碼都很簡單,只有少數地方值得提一下。首先,請求中的數據必須手工格式化爲 XML。閱讀了三篇關於使用文檔對象類型的文章之後,再來討論它是不是很簡單了?雖然不禁止在 JavaScript 中使用 DOM 創建 XML 文檔,但是在通過 GET 或 POST 請求發送到網絡上之前必須將 DOM 對象轉化成文本。因此使用常規字符串操作來格式化數據更簡單一些。當然,這樣很容易出現錯誤和誤輸入,因此在編寫處理 XML 的代碼時必須非常小心。

建立 XML 之後,按照和發送文本基本相同的方式打開連接。對於 XML 最好使用 POST 請求,因爲有些瀏覽器限制了 GET 請求字符串的長度,而 XML 可能很長,可以看到代碼段中把 GET 改成了 POST 方法。此外,XML 通過 send() 方法發送,而不是附加在請求 URL 最後的參數。這些都是非常細微的區別,很容易修改。

但是必須編寫一行新的代碼:

xmlHttp.setRequestHeader("Content-Type", "text/xml");



看起來很難理解,它只不過是告訴服務器要發送的是 XML 而不是一般的名/值對。無論哪種情況,發送的數據都是文本,但這裏使用 text/xml 或者 XML 作爲普通文本發送。如果使用名/值對,對應的行應該是:

xmlHttp.setRequestHeader("Content-Type", "text/plain");



如果忘記告訴服務器發送的是 XML,就會出現問題,因此不要忘掉這一步驟。

完成這些之後,剩下的就是調用 send() 並傳入 XML 字符串了。服務器將收到您的 XML 請求,並(假設已經做好了準備工作)接受 XML,解釋它,然後返回響應。實際上要做的只有這麼多 —— XML 請求只需要稍微修改代碼。

服務器端接受到XML做出什麼樣的相應,在下篇文章中將介紹。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章