AJAX
實現Ajax的標准方法是直接使用XMLHttpRequest(XHR)對象,也可以使用Ajax的封裝庫如Prototype或jQuery。
手動的創建XHR對象:
if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else if (window.ActiveXObject) {// 一般IE xhr = new ActiveXObject(“Microsoft.XMLHTTP”); }
調用XHR對象的open方法,“GET”方式請求URL:’
xhr.open( “GET”, “my-dynamic-content.jsp?id=” +encodeURI(myId), true );
回調方法來處理響應:
xhr.onreadystatechange = function(){ processReqChange(req); }
發送請求:
xhr.send(null);
XHR對象的全部細節(方法)如下:
方法open(method, url, async),打開一個URL連接,method為HTTP請求方式(POST/GET...),url為HTTP請求的URL路徑,async為是否創建一個異步請求(true/false)。
方法onreadystatechange,聲明一個方法對象(function Object)作為回調方法,類似於瀏覽器事件模型中的onclick、onload方法。
方法setRequestHeader(namevalue),設置HTTP請求的請求頭。
方法send(body),發送請求體,可以是字符串。
方法abort(),停止XHR對象監聽HTTP響應。
方法readyState,響應(response)生命周期的階段狀態,只有send方法被調用之后狀態值被填充或者類似於被set給readyState。
方法httpStatus,HTTP返回code,整數,只有響應達到被加載(返回到頁面)狀態時才會被填充code值如404等。
方法responseText,響應體(Javascript字符串),只有響應達到interactive狀態時才會設置響應體。
方法responseXML,響應體(XML文檔對象),只有響應達到interactive狀態時才會設置響應體。
方法getResponseHeader(name),通過名字讀取響應頭。
方法getAllResponseHeaders(),獲取所有響應頭名字的數組。
HTTP協議
HTTP是一個沒有狀態的(不會記住或存儲上一次的HTTP過程的狀態)請求-響應(request-response) 協議。

請求和響應都包含請求頭或響應頭header和可選的請求體或響應體body(自由的文本)。
只有POST請求包含一個body。
一個請求定義一個動作或方法(POST/GET...)。
請求和響應的Mime類型可以通過header中的Content-type進行設置。
常用的HTTP請求方式(99%的時間只需要使用POST和GET)
GET:嚴格的說,GET只用於獲取數據,而不會使web服務器(中的數據)發生變化。GET請求不包含請求體body,請求參數包含在URL的請求字符串中。
POST:用於更新web服務器上的數據,通過請求體body傳遞參數或數據(data);
REST風格的Web Service,通常使用HTTP verbs來映射CRUD操作:
PUT -- Create -- 對域模型(domain model)添加一個新的對象實例。
GET-- Read-- 從web服務器獲取已經存在的域模型對象。
POST-- Update-- 更新已經存在的域模型對象。
DELETE-- Delete-- 從域模型中刪除一個已經存在的對象。
常用的MIME類型
application/x-wwwform-urlencoded :經過編碼的鍵值對請求字符串(body),web服務器需要解碼字符串獲得參數。
text/xml,application/xml:Body是XML文檔。
text/plain:普通文本。
text/html, text/xhtml:Body是(X)HTML內容,web服務器端發送的標准web頁面或內容片段。
text/javascript:Body是一段JavaScript代碼。
image/png, image/jpeg, image/gif:Body是二進制圖像。
處理HTTP響應
xhr.onreadystatechange=function(){ if (xhr.readyState==4){ if (xhr.status==200){ parseResponse(xhr); }else{ //handle the HTTP error... } }; };
XHR對象的ReadyState值:
0 -- 未初始化 -- 請求還未被發送
1 -- 加載中 -- 響應還未到達(瀏覽器)
2 -- 加載完成 -- 可以讀取響應頭了
3 -- 活動的(Interactive) -- 響應體Body不完整,但是可以被讀取
4 -- 完成 -- 響應體Body是完整的
處理HTTP響應---parseResponse(xhr)
如果響應為HTML代碼如:
<table class=’item selected’> <tr> <td rowspan=’3’ valign=’top’><div class=’itemIcon’><img src=’../images/kmoon.png’></div></td> <td class=’itemTitle’>The Moon on a Stick</td> </tr> <tr> <td valign=’top’>What every project manager wants - and they want it yesterday!<br/><br/><i>NB: Stick not included.</i></td> </tr> <tr> <td><div class=’price’>$365.00</div></td> </tr> </tr> </table>
處理函數如(往id為myDiv的div中插入上述返回的HTML):
function parseResponse(xhr){ var div=document.getElementById(“myDiv”); div.innerHTML=xhr.responseText; }
如果響應為JSON格式的數據如:
{ imgSrc: “kmoon.png”, title: “The Moon on a Stick”, description: “What every project manager wants - and they want it yesterday!<br/><br/><i>NB: Stick not included.</i>”, price: “365.00” }
處理函數如:
function parseResponse(xhr){ var jsonObj=eval(“(“+xhr.responseText+”)”); setImgSrc(jsonObj.imgSrc); setTitle(jsonObj.title); }
如果響應為XML文檔或片段如:
<item imgSrc=”kmoon.png” price=”365.00”> <title>The Moon on a Stick</title> <description><![CDATA[What every project manager wants - and they want it yesterday!<br/><br/><i>NB: Stick not included.</i>]]></description> </item>
處理函數(還有其它方式解析XML,略)如:
function parseResponse(xhr){ var xmlDoc=xhr.responseXML; var item=xmlDoc.getElementsByTagName(‘item’)[0]; var imgSrc=item.getAttribute(‘imgSrc’); var title=item.getElementsByTagName(‘title’)[0].firstChild.data; setImgSrc(imgSrc); setTitle(title); }
一些流行的Ajax工具(js庫)
Prototype Scriptaculous dojo Yahoo User Interface (YUI) Ext sarissa Mochikit jQuery MooTools Ruby on Rails(Server端)GWT
Prototype創建Ajax請求:
new Ajax.Request( “my-dynamic-content.jsp”, {
method: “post”,
params: { id: myId }, onComplete: function(response){ parseResponse(response); } } );
jQuery創建Ajax請求:
$.post( “my-dynamic-content.jsp”, { id: myId }, function(xhr){ parseResponse(xhr); } );
