引言
要完整實(shí)現(xiàn)一個(gè)ajax異步調(diào)用和局部刷新,通常需要以下幾個(gè)步驟:
(1)創(chuàng)建xmlhttprequest對(duì)象,也就是創(chuàng)建一個(gè)異步調(diào)用對(duì)象.
(2)創(chuàng)建一個(gè)新的http請(qǐng)求,并指定該http請(qǐng)求的方法、url及驗(yàn)證信息.
(3)設(shè)置響應(yīng)http請(qǐng)求狀態(tài)變化的函數(shù).
(4)發(fā)送http請(qǐng)求.
(5)獲取異步調(diào)用返回的數(shù)據(jù).
(6)使用javascript和dom實(shí)現(xiàn)局部刷新.
1、創(chuàng)建xmlhttprequest對(duì)象
不同的瀏覽器使用的異步調(diào)用對(duì)象也有所不同,在ie瀏覽器中異步調(diào)用使用的是xmlhttp組件中的xmlhttprequest對(duì)象,而在netscape、firefox瀏覽器中則直接使用xmlhttprequest組件。因此,在不同瀏覽器中創(chuàng)建xmlhttprequest對(duì)象的方式都有所不同.
在ie瀏覽器中創(chuàng)建xmlhttprequest對(duì)象的方式如下所示:
var xmlhttprequest = new activexobject("microsoft.xmlhttp");
在netscape瀏覽器中創(chuàng)建xmlhttprequest對(duì)象的方式如下所示:
var xmlhttprequest = new xmlhttprequest();
由于無(wú)法確定用戶使用的是什么瀏覽器,所以在創(chuàng)建xmlhttprequest對(duì)象時(shí),最好將以上兩種方法都加上.如以下代碼所示:
<html> ???<head> ??????<title>創(chuàng)建xmlhttprequest對(duì)象</title> ??????<script language = "javascript" type = "text/javascript"> ??????<!-- ??????var xmlhttprequest;??//定義一個(gè)變量,用于存放xmlhttprequest對(duì)象 ??????function createxmlhttprequest()????//創(chuàng)建xmlhttprequest對(duì)象的方法 ??????{ ??????if(window.activexobject)???//判斷是否是ie瀏覽器 ??????{ ?????????xmlhttprequest = new activexobject("microsoft.xmlhttp");??//創(chuàng)建ie瀏覽器中的xmlhttprequest對(duì)象 ??????} ??????else if(window.xmlhttprequest)????//判斷是否是netscape等其他支持xmlhttprequest組件的瀏覽器 ??????{ ????????? xmlhttprequest = new xmlhttprequest();??//創(chuàng)建其他瀏覽器上的xmlhttprequest對(duì)象 ??????} ????} ?????? --> ??????</script> ??????createxmlhttprequst();???//調(diào)用創(chuàng)建對(duì)象的方法 ????</head> <body> </body> </html>
"if(window.activexobject)"用來(lái)判斷是否使用ie瀏覽器.其中activexoject并不是windows對(duì)象的標(biāo)準(zhǔn)屬性,而是ie瀏覽器中專有的屬性,可以用于判斷瀏覽器是否支持activex控件.通常只有ie瀏覽器或以ie瀏覽器為核心的瀏覽器才能支持active控件.
"else if(window.xmlhttprequest)"是為了防止一些瀏覽器既不支持activex控件,也不支持xmlhttprequest組件而進(jìn)行的判斷.其中xmlhttprequest也不是window對(duì)象的標(biāo)準(zhǔn)屬性,但可以用來(lái)判斷瀏覽器是否支持xmlhttprequest組件.
如果瀏覽器既不支持activex控件,也不支持xmlhttprequest組件,那么就不會(huì)對(duì)xmlhttprequest變量賦值.
2、創(chuàng)建http請(qǐng)求
創(chuàng)建了xmlhttprequest對(duì)象之后,必須為xmlhttprequest對(duì)象創(chuàng)建http請(qǐng)求,用于說(shuō)明xmlhttprequest對(duì)象要從哪里獲取數(shù)據(jù).通常可以是網(wǎng)站中的數(shù)據(jù),也可以是本地中其他文件中的數(shù)據(jù).
創(chuàng)建http請(qǐng)求可以使用xmlhttprequest對(duì)象的open()方法,其語(yǔ)法代碼如下所示:
xmlhttprequest.open(method,url,flag,name,password)
代碼中的參數(shù)解釋如下所示:
method:該參數(shù)用于指定http的請(qǐng)求方法,一共有g(shù)et、post、head、put、delete五種方法,常用的方法為get和post。
url:該參數(shù)用于指定http請(qǐng)求的url地址,可以是絕對(duì)url,也可以是相對(duì)url。
flag:該參數(shù)為可選參數(shù),參數(shù)值為布爾型。該參數(shù)用于指定是否使用異步方式。true表示異步方式、false表示同步方式,默認(rèn)為true。
name:該參數(shù)為可選參數(shù),用于輸入用戶名。如果服務(wù)器需要驗(yàn)證,則必須使用該參數(shù)。
password:該參數(shù)為可選參數(shù),用于輸入密碼。如果服務(wù)器需要驗(yàn)證,則必須使用該參數(shù)。通??梢允褂靡韵麓a來(lái)訪問(wèn)一個(gè)網(wǎng)站文件的內(nèi)容。
xmlhttprequest.open("get","http://www.aspxfans.com/booksupport/javascript/ajax.htm",true);
或者使用以下代碼來(lái)訪問(wèn)一個(gè)本地文件內(nèi)容:
xmlhttprequest.open("get","ajax.htm",true);
注意:如果html文件放在web服務(wù)器上,在netscape瀏覽器中的javascript安全機(jī)制不允許與本機(jī)之外的主機(jī)進(jìn)行通信。也就是說(shuō),使用open()方法只能打開(kāi)與html文件在同一個(gè)服務(wù)器上的文件。而在ie瀏覽器中則無(wú)此限制(雖然可以打開(kāi)其他服務(wù)器上的文件,但也會(huì)有警告提示)。
3、設(shè)置響應(yīng)http請(qǐng)求狀態(tài)變化的函數(shù)
創(chuàng)建完http請(qǐng)求之后,應(yīng)該就可以將http請(qǐng)求發(fā)送給web服務(wù)器了。然而,發(fā)送http請(qǐng)求的目的是為了接收從服務(wù)器中返回的數(shù)據(jù)。從創(chuàng)建xmlhttprequest對(duì)象開(kāi)始,到發(fā)送數(shù)據(jù)、接收數(shù)據(jù)、xmlhttprequest對(duì)象一共會(huì)經(jīng)歷以下5中狀態(tài)。
⑴未初始化狀態(tài)。在創(chuàng)建完xmlhttprequest對(duì)象時(shí),該對(duì)象處于未初始化狀態(tài),此時(shí)xmlhttprequest對(duì)象的readystate屬性值為0。
⑵初始化狀態(tài)。在創(chuàng)建完xmlhttprequest對(duì)象后使用open()方法創(chuàng)建了http請(qǐng)求時(shí),該對(duì)象處于初始化狀態(tài)。此時(shí)xmlhttprequest對(duì)象的readystate屬性值為1。
⑶發(fā)送數(shù)據(jù)狀態(tài)。在初始化xmlhttprequest對(duì)象后,使用send()方法發(fā)送數(shù)據(jù)時(shí),該對(duì)象處于發(fā)送數(shù)據(jù)狀態(tài),此時(shí)xmlhttprequest對(duì)象的readystate屬性值為2。
⑷接收數(shù)據(jù)狀態(tài)。web服務(wù)器接收完數(shù)據(jù)并進(jìn)行處理完畢之后,向客戶端傳送返回的結(jié)果。此時(shí),xmlhttprequest對(duì)象處于接收數(shù)據(jù)狀態(tài),xmlhttprequest對(duì)象的readystate屬性值為3。
⑸完成狀態(tài)。xmlhttprequest對(duì)象接收數(shù)據(jù)完畢后,進(jìn)入完成狀態(tài),此時(shí)xmlhttprequest對(duì)象的readystate屬性值為4。此時(shí)接收完畢后的數(shù)據(jù)存入在客戶端計(jì)算機(jī)的內(nèi)存中,可以使用responsetext屬性或responsexml屬性來(lái)獲取數(shù)據(jù)。
只有在xmlhttprequest對(duì)象完成了以上5個(gè)步驟之后,才可以獲取從服務(wù)器端返回的數(shù)據(jù)。因此,如果要獲得從服務(wù)器端返回的數(shù)據(jù),就必須要先判斷xmlhttprequest對(duì)象的狀態(tài)。
xmlhttprequest對(duì)象可以響應(yīng)readystatechange事件,該事件在xmlhttprequest對(duì)象狀態(tài)改變時(shí)(也就是readystate屬性值改變時(shí))激發(fā)。因此,可以通過(guò)該事件調(diào)用一個(gè)函數(shù),并在該函數(shù)中判斷xmlhttprequest對(duì)象的readystate屬性值。如果readystate屬性值為4則使用responsetext屬性或responsexml屬性來(lái)獲取數(shù)據(jù)。具體代碼如下所示:
//設(shè)置當(dāng)xmlhttprequest對(duì)象狀態(tài)改變時(shí)調(diào)用的函數(shù),注意函數(shù)名后面不要添加小括號(hào) xmlhttprequest.onreadystatechange = getdata; //定義函數(shù) function getdata() { ???//判斷xmlhttprequest對(duì)象的readystate屬性值是否為4,如果為4表示異步調(diào)用完成 ???if(xmlhttprequest.readystate == 4) ???{ ???/設(shè)置獲取數(shù)據(jù)的語(yǔ)句 ???} }
4、設(shè)置獲取服務(wù)器返回?cái)?shù)據(jù)的語(yǔ)句
如果xmlhttprequest對(duì)象的readystate屬性值等于4,表示異步調(diào)用過(guò)程完畢,就可以通過(guò)xmlhttprequest對(duì)象的responsetext屬性或responsexml屬性來(lái)獲取數(shù)據(jù)。
但是,異步調(diào)用過(guò)程完畢,并不代表異步調(diào)用成功了,如果要判斷異步調(diào)用是否成功,還要判斷xmlhttprequest對(duì)象的status屬性值,只有該屬性值為200,才表示異步調(diào)用成功,因此,要獲取服務(wù)器返回?cái)?shù)據(jù)的語(yǔ)句,還必須要先判斷xmlhttprequest對(duì)象的status屬性值是否等于200,如以下代碼所示:
if(xmlhttprequst.status == 200) ??{ ?????//使用以下語(yǔ)句將返回結(jié)果以字符串形式輸出 ?????document.write(xmlhttprequest.responsetext); ?????//或者使用以下語(yǔ)句將返回結(jié)果以xml形式輸出 ?????//document.write(xmlhttprequest.responsexml); ??}
注意:如果html文件不是在web服務(wù)器上運(yùn)行,而是在本地運(yùn)行,則xmlhttprequest.status的返回值為0。因此,如果該文件在本地運(yùn)行,則應(yīng)該加上xmlhttprequest.status == 0的判斷。
通常將以上代碼放在響應(yīng)http請(qǐng)求狀態(tài)變化的函數(shù)體內(nèi),如以下代碼所示:
//設(shè)置當(dāng)xmlhttprequest對(duì)象狀態(tài)改變時(shí)調(diào)用的函數(shù),注意函數(shù)名后面不要添加小括號(hào) xmlhttprequest.onreadystatechange = getdata; //定義函數(shù) ??function getdata() ??{ ????//判斷xmlhttprequest對(duì)象的readystate屬性值是否為4,如果為4表示異步調(diào)用完成 ????if(xmlhttprequest.readystate==4) ????{ ???????//設(shè)置獲取數(shù)據(jù)的語(yǔ)句 ???????if(xmlhttprequest.status == 200 || xmlhttprequest.status == 0) ???????{ ??????????//使用以下語(yǔ)句將返回結(jié)果以字符串形式輸出 ??????????document.write(xmlhttprequest.responsetext); ??????????//或者使用以下語(yǔ)句將返回結(jié)果以xml形式輸出 ??????????//docunment.write(xmlhttprequest.responsexml); ???????} ?????} ??}
5、發(fā)送http請(qǐng)求
在經(jīng)過(guò)以上幾個(gè)步驟的設(shè)置之后,就可以將http請(qǐng)求發(fā)送到web服務(wù)器上去了。發(fā)送http請(qǐng)求可以使用xmlhttprequest對(duì)象的send()方法,其語(yǔ)法代碼如下所示:
xmlhttprequest.send(data)
其中data是個(gè)可選參數(shù),如果請(qǐng)求的數(shù)據(jù)不需要參數(shù),即可以使用null來(lái)替代。data參數(shù)的格式與在url中傳遞參數(shù)的格式類似,以下代碼為一個(gè)send()方法中的data參數(shù)的示例:
name=myname&value=myvalue
只有在使用send()方法之后,xmlhttprequest對(duì)象的readystate屬性值才會(huì)開(kāi)始改變,也才會(huì)激發(fā)readystatechange事件,并調(diào)用函數(shù)。
6、局部更新
在通過(guò)ajax的異步調(diào)用獲得服務(wù)器端數(shù)據(jù)之后,可以使用javascript或dom來(lái)將網(wǎng)頁(yè)中的數(shù)據(jù)進(jìn)行局部更新。常用的局部更新的方式有以下3種:
⑴表單對(duì)象的數(shù)據(jù)更新
表單對(duì)象的數(shù)據(jù)更新,通常只要更改表單對(duì)象的value屬性值,其語(yǔ)法代碼如下所示:
formobject.value = "新數(shù)值"
有關(guān)表單對(duì)象的數(shù)據(jù)更新的示例如以下代碼所示:
<html> ??<head> ??<title>局部更新</title> ??<script language = "javascript" type = "text/javascript"> ??<!-- ??function changedata() ??{ ?????document.myform.mytext.value = "更新后的數(shù)據(jù)" ??} ??--> ??</head> ??<body> ?????<form name = "myform"> ?????<input type = "text" value = "原數(shù)據(jù)" name = "mytext"> ?????<input type = "button" value = "更新數(shù)據(jù)" onclick = "changedata()"> ?????</form> ???</body> </html>
⑵ie瀏覽器中標(biāo)簽間文本的更新
在html代碼中,除了表單元素之外,還有很多其他的元素,這些元素的開(kāi)始標(biāo)簽與結(jié)束標(biāo)簽之間往往也會(huì)有一點(diǎn)文字(如以下代碼所示),對(duì)這些文字的更新,也是局部更新的一部分。
<p>文字</p> 文字 <div>文字</div> <label>文字</label> <b>文字</b> <i>文字</i>
在ie瀏覽器中,innertext或innerhtml屬性可以用來(lái)更改標(biāo)簽間文本的內(nèi)容。其中innertext屬性用于更改開(kāi)始標(biāo)簽與結(jié)束標(biāo)簽之間的純文本內(nèi)容,而innerhtml屬性用于更改html內(nèi)容。如以下代碼所示:
<html> <head> <title>局部更新</title> <script language = "javascript" type = "text/javascript"> ????<!-- ????function changedata() ????{ ???????mydiv.innertext = "更新后的數(shù)據(jù)"; ????} ????????????????????????????????? --> </script> </head> <body> ???<div id = "mydive">原數(shù)據(jù)</div> ???<input type = "button" value = "更新數(shù)據(jù)" onclick = "changedata()"> </body> </html>
⑶dom技術(shù)的局部刷新
innertext和innerhtml兩個(gè)屬性都是ie瀏覽器中的屬性,在netscape瀏覽器中并不支持該屬性。但無(wú)論是ie瀏覽器還是netscape瀏覽器,都支持dom。在dom中,可以修改標(biāo)簽間的文本內(nèi)容。
在dom中,將html文檔中的每一對(duì)開(kāi)始標(biāo)簽和結(jié)束標(biāo)簽都看成是一個(gè)節(jié)點(diǎn)。例如html文檔中有一個(gè)標(biāo)簽如下所示,那么該標(biāo)簽在dom中稱之為一個(gè)“節(jié)點(diǎn)”。
<div id = "mydiv">原數(shù)據(jù)</div>
在dom中使用getelementbyid()方法可以通過(guò)id屬性值來(lái)查找該標(biāo)簽(或者說(shuō)是節(jié)點(diǎn)),如以下語(yǔ)句所示:
var node = document.getelementbyid("mydiv");
注意:在一個(gè)html文檔中,每個(gè)標(biāo)簽中的id屬性值是不能重復(fù)的。因此,使用getelementbyid()方法獲得的節(jié)點(diǎn)是唯一的。
在dom中,認(rèn)為開(kāi)始標(biāo)簽與結(jié)束標(biāo)簽之間的文本是該節(jié)點(diǎn)的子節(jié)點(diǎn),而firstchild屬性可以獲得一個(gè)節(jié)點(diǎn)下的第1個(gè)子節(jié)點(diǎn)。如以下代碼可以獲得<div>節(jié)點(diǎn)下的第1個(gè)子節(jié)點(diǎn),也就是<div>標(biāo)簽與</div>標(biāo)簽之間的文字節(jié)點(diǎn)。
node.firstchild
注意,以上代碼獲得的是文字節(jié)點(diǎn),而不是文字內(nèi)容。如果要獲得節(jié)點(diǎn)的文字內(nèi)容,則要使用節(jié)點(diǎn)的nodevalue屬性。通過(guò)設(shè)置nodevalue屬性值,可以改變文字節(jié)點(diǎn)的文本內(nèi)容。完整的代碼如下所示:
<html> <head> <title>局部更新</title> <script language = "javascript" type = "text/javascript"> <!-- ??function changedata() ??{ ??//查找標(biāo)簽(節(jié)點(diǎn)) ??var node = document.getelementbyid("mydiv"); ??//在dom中標(biāo)簽中的文字被認(rèn)為是標(biāo)簽中的子節(jié)點(diǎn) ??//節(jié)點(diǎn)的firstchild屬性為該節(jié)點(diǎn)下的第1個(gè)子節(jié)點(diǎn) ??//nodevalue屬性為節(jié)點(diǎn)的值,也就是標(biāo)簽中的文本值 ??node.firstchild.nodevalue = "更新后的數(shù)據(jù)"; ??} ??--> </script> </head> </html>
注意:目前主流的瀏覽器都支持dom技術(shù)的局部刷新。
7、完整的ajax實(shí)例
<html> <head> <title>ajax實(shí)例</title> <script language="javascript" type="text/javascript">???? ?????????<!-- ??????????var xmlhttprequest;??//定義一個(gè)變量用于存放xmlhttprequest對(duì)象 ??????????//定義一個(gè)用于創(chuàng)建xmlhttprequest對(duì)象的函數(shù) ??????????function createxmlhttprequest() ??????????{ ??????????if(window.activexobject) ??????????{ ??????????//ie瀏覽器的創(chuàng)建方式 ??????????xmlhttprequest = new activexobject("microsoft.xmlhttp"); ?????????}else if(windew.xmlhttprequest) ?????????{ ?????????//netscape瀏覽器中的創(chuàng)建方式 ?????????xmlhttprequest = new xmlhttprequest(); ?????????} ?????????} ?????????//響應(yīng)http請(qǐng)求狀態(tài)變化的函數(shù) ?????????function httpstatechange() ?????????{ ?????????//判斷異步調(diào)用是否完成 ?????????if(xmlhttprequest.readystate == 4) ?????????{ ?????????//判斷異步調(diào)用是否成功,如果成功開(kāi)始局部更新數(shù)據(jù) ?????????if(xmlhttprequest.status == 200||xmlhttprequest.status == 0) ?????????{ ?????????//查找節(jié)點(diǎn) ?????????var node = document.getelementbyid("mydiv"); ?????????//更新數(shù)據(jù) ????????? node.firstchild.nodevalue = xmlhttprequest?.responsetext; ?????????} ?????????else ?????????{ ??????????//如果異步調(diào)用未成功,彈出警告框,并顯示出錯(cuò)信息 ????????? alert("異步調(diào)用出錯(cuò)/n返回的http狀態(tài)碼為:"+xmlhttprequest.status + "/n返回的http狀態(tài)信息為:" + xmlhttprequest.statustext); ????????} ?????? } ???????} ???????//異步調(diào)用服務(wù)器段數(shù)據(jù) ?????? function getdata(name,value) ??????{??????????????????? ??????//創(chuàng)建xmlhttprequest對(duì)象 ??????createxmlhttprequest(); ??????if(xmlhttprequest!=null) ??????{ ??????//創(chuàng)建http請(qǐng)求 ??????xmlhttprequest.open("get","ajax.text",true) ??????//設(shè)置http請(qǐng)求狀態(tài)變化的函數(shù) ??????xmlhttprequest.onreadystatechange = httpstatechange; ??????//發(fā)送請(qǐng)求 ??????xmlhttprequest.send(null); ??????} ???} ???--> ???</script> </head> <body> ???<div id="mydiv">原數(shù)據(jù)</div> ???<input type = "button" value = "更新數(shù)據(jù)" onclick = "getdata()"> </body> </html>
總結(jié)
到此這篇關(guān)于實(shí)現(xiàn)ajax異步調(diào)用和局部刷新的基本步驟的文章就介紹到這了,更多相關(guān)實(shí)現(xiàn)ajax的步驟內(nèi)容請(qǐng)搜索碩編程以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持碩編程!