AJAX當我在前兩年第一次看到這個名字的時候,我有些感覺頭大。因為又出了一門新語言,自從WEB應(yīng)用流行起來時,就層出不窮的新技術(shù)。那時在網(wǎng)上看到《Ajax實戰(zhàn)》,很郁悶,又是500多頁的新技術(shù)…。但自從接觸WEB以來,很多看似復(fù)雜而艱難的東西就像窗戶紙一樣。AJAX也不例外,不是就對當前頁面數(shù)據(jù)的更新嗎!(說大話了,雖然我還沒用熟它。但它確實沒有相像中的那么難。)
開始整理!
一、AJAX簡介
1. AJAX簡介
AJAX全稱為“Asynchronous JavaScript and XML”(異步JavaScript和XML),是一種創(chuàng)建交互式網(wǎng)頁應(yīng)用的網(wǎng)頁開發(fā)技術(shù)。根據(jù)Ajax提出者Jesse James Garrett建議[1],它:
1. 使用XHTML+CSS來表示信息;
2. 使用JavaScript操作DOM(Document Object Model)進行動態(tài)顯示及交互;
3. 使用XML和XSLT進行數(shù)據(jù)交換及相關(guān)操作;
4. 使用XMLHttpRequest對象與Web服務(wù)器進行異步數(shù)據(jù)交換;
5. 使用JavaScript將所有的東西綁定在一起。
6. 使用SOAP以XML的格式來傳送方法名和方法參數(shù)。
類似于DHTML或LAMP,AJAX不是指一種單一的技術(shù),而是有機地利用了一系列相關(guān)的技術(shù)。事實上,一些基于AJAX的“派生/合成”式(derivative/composite)的技術(shù)正在出現(xiàn),如“AFLAX”。
AJAX的應(yīng)用使用支持以上技術(shù)的Web瀏覽器作為運行平臺。這些瀏覽器目前包括:Internet Explorer、Mozilla、Firefox、Opera、Konqueror及Mac OS的Safari。但是Opera不支持XSL格式對象,也不支持XSLT[2]。
比如google搜索的提示框,google的地圖都是使用AJAX來實現(xiàn)的。
AJAX技術(shù),不用刷新整個頁面即可完成與服務(wù)器通訊并更新頁面顯示數(shù)據(jù)。
AJAX不用刷新整個頁面便可與服務(wù)器通訊的辦法——XMLHttpRequest:該對象是對 JavaScript 的一個擴展,可使網(wǎng)頁與服務(wù)器進行通信。是創(chuàng)建 Ajax 應(yīng)用的最佳選擇。實際上通常把 Ajax 當成 XMLHttpRequest 對象的代名詞,XMLHttpRequest是核心!
2.AJAX工具包
通過簡介我們知道,AJAX不是一項獨有的新技術(shù)是多種技術(shù)的創(chuàng)新混合。
a) 服務(wù)器端語言:服務(wù)器需要具備向瀏覽器發(fā)送特定信息的能力,Ajax與服務(wù)器端語言無關(guān)。
b) XML (eXtensible Markup Language,可擴展標記語言) 是一種描述數(shù)據(jù)的格式。Aajx 程序需要某種格式化的格式來在服務(wù)器和客戶端之間傳遞信息,XML 是其中的一種選擇。
c) XHTML(eXtended Hypertext Markup Language,使用擴展超媒體標記語言)和 CSS(Cascading Style Sheet,級聯(lián)樣式單)標準化呈現(xiàn)。
d) DOM(Document Object Model,文檔對象模型)實現(xiàn)動態(tài)顯示和交互。
e) 使用XMLHTTP組件XMLHttpRequest對象進行異步數(shù)據(jù)讀取。
f) 使用JavaScript綁定和處理所有數(shù)據(jù)。
3.AJAX的缺陷
老佟在講解新技術(shù)時,時常說的話——沒有完美的技術(shù)。AJAX也不例外:
a) 由 Javascript 和 AJAX 引擎的不同導(dǎo)致的瀏覽器的兼容。
b) 頁面局部刷新,導(dǎo)致后退等功能失效。
c) 對流媒體的支持沒有FLASH、Java Applet好。
d) 一些手持設(shè)備(如手機、PDA等)支持性差。
AJAX具有這些缺陷,但它帶給人們的體驗和技術(shù)的發(fā)展是功不可沒的!
二、XMLHttpRequest
1.簡介
XMLHttprequest最早是在IE5中以ActiveX實現(xiàn)的,但它至今仍不是W
2.創(chuàng)建XMLHttpRequest對象
我們將它單獨拿出來做成一個函數(shù),因為只創(chuàng)建XMLHttpRequest對象一次即可:
function getXMLHttpRequest(){ if(window.XMLHttpRequest){ return new XMLHttpRequest(); }else if(window.ActiveXObject){ return new ActiveXObject("Microsoft.XMLHTTP"); }else{ return null; } } |
在需要XMLHttpRequest對象的地方,直接調(diào)用上面的方法獲得即可!
3.XMLHttpRequest的方法
方法 | 描述 |
abort() | 停止當前的請求 |
getAllResponseHeader() | 將HTTP請求的所有響應(yīng)首部作為鍵/值返回 |
getResponseHeader(“header”) | 返回指定首部的串值 |
Open(“method”,”url”) | 建立服務(wù)器的調(diào)用。Method可以是GET、POST或PUT,URL可以是相對URL或絕對URL。 |
Seng(content) | 向服務(wù)器發(fā)送請求。 |
setRequestHeader(“header”,”value”) | 把指定首部設(shè)置為所提供的值。在設(shè)置任何首部之前必須先調(diào)用open()。 |
4.XMLHttpRequest的屬性
屬性 | 描述 |
readyState | 請求狀態(tài),狀態(tài)值:0,未初始化。1,正在加載。2,已經(jīng)加載。3,交互中。4,完成。 |
onreadystatechange | 當readyState狀態(tài)值被改變時,都會調(diào)用這個屬性指定的JavaScript函數(shù)。 |
responseText | 服務(wù)器的響應(yīng),表示為一個串。 |
responseXML | 服務(wù)器的XML響應(yīng),可以解析為 DOM對象。 |
status | 服務(wù)器響應(yīng)的HTTP狀態(tài)碼。 |
statusText | 服務(wù)器響應(yīng)的HTTP狀態(tài)碼的相應(yīng)文本。 |
三、XMLHttpRequest發(fā)送與接收請求
XMLHttpRequest與服務(wù)器進行通訊包含以下三個關(guān)鍵部分:
1. onreadystatechange事件處理函數(shù)
2. open方法
3. seng方法
在發(fā)送和接收請求之前先了解XMLHttpRequest的onreadystatechange屬性。為此屬性指定一個無參數(shù)的函數(shù)。在onreadystatechange指定的函數(shù)中通過判斷XMLHttpRequest的readyState值,來進行相應(yīng)的處理。比如,readyState為4時說明服務(wù)器處理XMLHttpRequest的請求完成,這時我們就可以獲取服務(wù)器的響應(yīng)數(shù)據(jù)。readyState值是被服務(wù)器改變的。
1.發(fā)送請求
1) 準備請求
XMLHttpRequestObj .open(method, url, asynch),open 方法允許程序員用一個Ajax調(diào)用向服務(wù)器發(fā)送請求:
method:請求類型,類似 “GET”或”POST”的字符串。若只想從服務(wù)器檢索一個文件,而不需要發(fā)送任何數(shù)據(jù),使用GET(可以在GET請求里通過附加在URL上的查詢字符串來發(fā)送數(shù)據(jù),不過數(shù)據(jù)大小限制為2000個字符)。若需要向服務(wù)器發(fā)送數(shù)據(jù),用POST。在某些情況下,有些瀏覽器會把多個XMLHttpRequest請求的結(jié)果緩存在同一個URL。如果對每個請求的響應(yīng)不同,就會帶來不好的結(jié)果。在此將時間戳追加到URL的最后(url+”?time=”+new Date()),就能確保URL的唯一性,從而避免瀏覽器緩存結(jié)果。
url:路徑字符串,指向你所請求的服務(wù)器上服務(wù)的路徑。可以是絕對路徑或相對路徑。
asynch:表示請求是否要異步傳輸,默認值為true。指定true,在讀取后面的腳本之前,不需要等待服務(wù)器的響應(yīng)。指定false,當腳本處理過程經(jīng)過這點時,會停下來,一直等到Ajax請求執(zhí)行完畢再繼續(xù)執(zhí)行。
2) 發(fā)送請求
XMLHttpRequestObj .send(data),send 方法可為已經(jīng)待命的請求(open設(shè)置的準備就地正法)發(fā)送指令:
data:將要傳遞給服務(wù)器的字符串。若選用的是 GET 請求,則不會發(fā)送任何數(shù)據(jù), 給 send 方法傳遞 null 即可:request.send(null);。當向send()方法提供參數(shù)時,要確保open()中指定的方法是POST,如果沒有數(shù)據(jù)作為請求體的一部分發(fā)送,則使用null。
3) 請求信息頭
XMLHttpRequestObj .setRequestHeader(header,value):
當瀏覽器向服務(wù)器請求頁面時,它會伴隨這個請求發(fā)送一組首部信息。這些首部信息是一系列描述請求的元數(shù)據(jù)(metadata)。首部信息用來聲明一個請求是 GET 還是 POST。Ajax 請求中,發(fā)送首部信息的工作可以由 setRequestHeader該完成。
header: 首部的名字.
value:首部的值。
如果用POST 請求向服務(wù)器發(fā)送數(shù)據(jù),需要將“Content-type”的首部設(shè)置為 “application/x-www-form-urlencoded”。它會告知服務(wù)器正在發(fā)送數(shù)據(jù),并且數(shù)據(jù)已經(jīng)符合URL編碼了。該方法必須在open()之后才能調(diào)用。
2.接收請求
當一個請求被響應(yīng)后,XMLHttpRequest的如下屬性被設(shè)置(看前邊的表它們分別代表什么意思):readyState、status、responseText、responseXML。
1) readyState,表示Ajax請求的當前狀態(tài)。
n 0 代表未初始化,還沒有調(diào)用 open 方法。
n 1 代表正在加載,open 方法已被調(diào)用,但 send 方法還沒有被調(diào)用。
n 2 代表已加載完畢,send 已被調(diào)用請求已經(jīng)開始。
n 3 代表交互中,服務(wù)器正在發(fā)送響應(yīng)。
n 4 代表完成,服務(wù)器響應(yīng)發(fā)送完畢。
每次 readyState 值的改變,都會觸發(fā) readystatechange 事件。如果把 onreadystatechange 事件處理函數(shù)指定為一個函數(shù),那么每次 readyState 值的改變都執(zhí)行該函數(shù)。
readyState 值的變化會因瀏覽器的不同而有所差異。但是,當請求結(jié)束的時候,每個瀏覽器都會把 readyState 的值統(tǒng)一設(shè)為 4。我們常處理readyState為4的應(yīng)用。
2) 服務(wù)器的響應(yīng)信息頭,三位數(shù)的狀態(tài)碼是服務(wù)器發(fā)送的響應(yīng)中最重要的頭部信息,并且屬于超文本傳輸協(xié)議中的一部分。常用狀態(tài)碼及其含義:
l 404 沒找到頁面(not found)
l 403 禁止訪問(forbidden)
l 500 內(nèi)部服務(wù)器出錯(internal service error)
l 200 一切正常(ok)
l 304 沒有被修改(not modified)
在 XMLHttpRequest 對象中,服務(wù)器發(fā)送的狀態(tài)碼都保存在 status 屬性里。通過把這個值和 200 或 304 比較,可以確保服務(wù)器是否已發(fā)送了一個成功的響應(yīng)!我們以此為標記,決定是否處理響應(yīng)信息哦!~
3) responseText,此屬性包含了從服務(wù)器發(fā)送的數(shù)據(jù)。它是一個HTML,XML或普通文本,這取決于服務(wù)器發(fā)送的內(nèi)容。
當 readyState 屬性值變成 4 時,responseText 屬性可用,表明 Ajax 請求已經(jīng)結(jié)束。我們通過此取獲取服務(wù)器響應(yīng)的信息,一般為HTML或JSON信息。我們可以直接使用HTML響應(yīng)內(nèi)容,如果響應(yīng)內(nèi)容為JSON,我們必須獲取JSON體中的休息。
4) responseXML
如果服務(wù)器返回的是XML,那么數(shù)據(jù)將儲存在responseXML 屬性中。
只用服務(wù)器發(fā)送了帶有正確首部信息的數(shù)據(jù)時, responseXML 屬性才是可用的。 MIME 類型必須為 text/xml。我們通過此取獲取服務(wù)器響應(yīng)的信息,一般為XML信息。我們可以使用DOM獲取XML中的響應(yīng)內(nèi)容。
三、XMLHttpRequest響應(yīng)內(nèi)容的數(shù)據(jù)格式
在服務(wù)器端 AJAX 是一門與語言無關(guān)的技術(shù),在業(yè)務(wù)邏輯層使用何種服務(wù)器端語言都可以。
從服務(wù)器端接收數(shù)據(jù)的時候,那些數(shù)據(jù)必須以瀏覽器能夠理解的格式來發(fā)送。服務(wù)器端的編程語言只能以如下 3 種格式返回數(shù)據(jù):
l XML
l JSON
l HTML
1.HTML
還記得最初編寫的Serlvet嗎?在Serlvet中直接向輸出流打印HTML信息,JSP頁面被翻譯為Servlet時,也是通過輸出流向瀏覽器輸出HTML信息。瀏覽器,直接顯示即可。所以在XMLHttpRequest處理請求信息時,可以直接使用DOM對象的innerHtml屬性或JQuery對象的html()方法,將responseText文本內(nèi)容直接添加到頁面元素節(jié)點中。
雖然這使用HTML做為響應(yīng)數(shù)據(jù)格式十分方便快捷,但當需要更新一篇文檔的多個部分時HTML就不大合適了,并且innerHtml不是w
2.XML
XML是WEB的世界能用語言,我們可以自定義XML格式,并且可以通過DOM對象完全操作XML。使用XML作為響應(yīng)數(shù)據(jù)的格式,必須保證XML的頭部信息正確,比如:“<?xml version="1.0" encoding="utf-8"?>”。若這個格式不正確,那么responseXML的值將是空的。
使用XML的最大難處是,如果XML的內(nèi)容龐大或復(fù)雜,使用DOM解析XML數(shù)據(jù)是痛苦的。
3. JSON
這個東西在我接觸WEB時就看見它,甚至在GWT的也有看見它。當時感覺比較神秘!~~JSON是什么呢?
JSON(JavaScript Object Notation)一種簡單的數(shù)據(jù)格式,比xml更輕巧。JSON是JavaScript原生格式,這意味著在JavaScript中處理JSON數(shù)據(jù)不需要任何特殊的API或工具包。
JSON的規(guī)則很簡單:對象是一個無序的“‘名稱/值’對”集合。一個對象以“{”(左括號)開始,“}”(右括號)結(jié)束。每個“名稱”后跟一個“:”(冒號);“‘名稱/值’對”之間使用“,”(逗號)分隔。如:
var $itcast = { "name":"itcast", "birthday":"2000", "contact":"123456789", "address":[{"country":"china","city":" {"country":" } |
JSON,使用:取代=號。每一條賦值語句使用,號分隔。整體使用{}包圍,也可以{}潛逃使用。數(shù)組使用[]包圍,成員之間使用,號分隔。
JSON中的成員值可以是字符串,數(shù)字或者布爾值也可以是函數(shù)。
如使用“$ itcast.name”獲得“itcast”,使用“$ itcast.address[0].country”獲取“china”。
JSON 只是一種文本字符串。它被存儲在 responseText 屬性中為了讀取存儲在 responseText 屬性中的 JSON 數(shù)據(jù),需要使用 JavaScript 的 eval函數(shù)。eval 會把字符串參數(shù)當作 JavaScript 代碼來執(zhí)行。因為 JSON 的字符串就是由 JavaScript 代碼構(gòu)成的,所以它本身是可執(zhí)行的。
JSON提供了json.js包,下載http://www.json.org/json.js后,可以使用parseJSON()方法將字符串解析成 JS 對象。
使用JSON做為響應(yīng)內(nèi)容的數(shù)據(jù)格式十分靈巧,而且不需要設(shè)置數(shù)據(jù)格式。但它的語法過于嚴謹,并且eval函數(shù)存在風險,比如服務(wù)器發(fā)送了一個無限循環(huán)的JSON內(nèi)容…。
若應(yīng)用程序不需要與其他應(yīng)用程序共享數(shù)據(jù)的時候,使用 HTML 片段來返回數(shù)據(jù)是最簡單的。
如果數(shù)據(jù)需要重用,JSON 文件是個不錯的選擇,其在性能和文件大小方面有優(yōu)勢。
當遠程應(yīng)用程序未知時,XML 文檔是首選,因為 XML 是 web 服務(wù)領(lǐng)域的 “世界語”。
四、使用JQuery操作AJAX
使用JQuery操作AJAX十分簡便,在 jQuery 中最底層的方法是$.ajax(),第二層是load(),$.get() 和 $.post(),第三層是 $.getScript() 和 $.getJSON()。
1.load方法
load(url, [data], [callback]),它前將響應(yīng)信息中的HTML數(shù)據(jù)直接插入到DOM中。比如$(“#id”).load(url,data,callbackfunc);直接將響應(yīng)信息插入到id指向的元素節(jié)點中。
我們也可以使用選擇器或過濾器來選取響應(yīng)數(shù)據(jù)中的某一部分內(nèi)容,方法是在url參數(shù)后邊加上過濾器,中間使用空格分隔。如,$(“#id”).load(url+” ”+”a:first”,data,callbackfunc);,就是選取返回信息中的第一個a元素插入到id指定的元素中。
data與callback可以根據(jù)需要指定或不指定。當指定data時,load函數(shù)會設(shè)置請求方式為post,否則為get。Callbackfunc在處理完成才能繼續(xù)的操作,這個回調(diào)函數(shù)有三個參數(shù):代表請求返回內(nèi)容的 data、代表請求狀態(tài)的 textStatus 對象和 XMLHttpRequest 對象。
2.get或post方法
get()和post()方法使用get和post方式來進行異步請求。它的結(jié)構(gòu)是:get(url, [data], [callback], [type]);和post(url, [data], [callback], [type]);。
它們的回調(diào)函數(shù)只有兩個參數(shù):data代表返回的內(nèi)容,可以是XML文檔、JSON 文件或HTML片段等;textstatus代表請求狀態(tài),其值可能為:succuss、error、notmodify、timeout 四種。
get()和post()方法是JQuery中的全局函數(shù),而find()等方法都是對JQuery對象進行操作的方法。
(具體細節(jié)可以查看JQuery的幫助手冊)
3.序列化元素
JQuery為準備“發(fā)送到服務(wù)器的 key/value 數(shù)據(jù)”提供了一個簡化的方法:serialize(),該方法作用于一個JQuery對象,能將DOM元素內(nèi)容序列化為字符串,用于 Ajax 請求。
比如,我們有一個登陸表單:
$.get(“ajax/login”,{“username”:$(“#username”).val(),”password”:$(“#password”).val()},function(data,textStatus){alert(data)});
如果這是一個用戶注冊的表單呢?需要手動填寫所有這些信息?No,serialize可以幫我們解決這個問題。如下:
$.get(“ajax/login”,$(“#loginform”).serialize() ,function(data,textStatus){alert(data)});
OK,這樣就搞定了。Serialize不僅可以用于Form表單,還可以用在其他有“key/value”的地方。
使用 serialize() 方法可以自動完成對參數(shù)的 url 編碼。
因為該方法作用于JQuery 對象, 所以不光只要表單能使用,其它選擇器選取的元素也能使用它。
五、其他
JQuery BlockUI Plugin一個比較實用的JQuery插件,將用戶向服務(wù)器提交請求時,它會獨占整個頁面并顯示“Please wait…”。直到服務(wù)器響應(yīng)完成時,它才退出顯示,將頁面交還給用戶。我們只需要在“$(function(){…}”中添加下面兩句代碼即可,別忘記引入插件的js文件哦!
$().ajaxStart($.blockUI); $().ajaxStop($.unblockUI); |
Ok!加油!