1.1什么是Ajax
? ? ? ?AsynchronousJavascriptAndXml(異步的JavaScript和Xml)。是一種用來改善用戶體驗的技術(shù),其實質(zhì)是利用瀏覽器內(nèi)置的一個特殊對象(XMLHttpRequest玄括,一般稱之為Ajax對象)異步地(Ajax對象在向服務(wù)器發(fā)送請求時,瀏覽器并不會銷毀當(dāng)前頁面沿癞,用戶仍然可以對當(dāng)前頁面作其他的操作)向服務(wù)器發(fā)送請求躁绸,服務(wù)器送回部分?jǐn)?shù)據(jù)(不是一個完整的新的頁面,而是文本或者Xml文檔)枷莉,在瀏覽器端娇昙,可以利用這些數(shù)據(jù)部分更新當(dāng)前頁面。整個過程笤妙,頁面無刷新冒掌,不打斷用戶的操作。
? ? ? 以前蹲盘,都是先銷毀原來的頁面股毫,然后發(fā)送請求,等待服務(wù)器發(fā)送響應(yīng)召衔,再生成新頁面铃诬。
Ajax的工作流程:
1.2Ajax對象:如何獲得Ajax對象
? ? ? 由于XMLHttpRequest(Ajax對象)沒有標(biāo)準(zhǔn)化,所以要區(qū)分瀏覽器薄嫡。
? ? ? function getXhr(){ ? ?//注意:后面的案例都將用到此函數(shù)
? ? ? ? ? ? ? ?var ?xhr=null;
? ? ? ? ? ? ?if(window.XMLHttpRequest){
? ? ? ? ? ? ? ? ? ? ?xhr=newXMLHttpRequest();//非IE瀏覽器
? ? ? ? ? ? ?}else{
? ? ? ? ? ? ? ? ? ? ?xhr=newActiveXObject('Microsoft.XMLHttp');//IE瀏覽器
? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?return xhr;
? ? ?}
注意事項:后面的案例也會用到以下函數(shù)
function $(id){ //依據(jù)id返回dom節(jié)點
? ? ? ? ? ? return document.getElementByid(id);
}
function $F(id){ //返回id對應(yīng)的值
? ? ? ? return $(id).value;
}
1.3Ajax對象的屬性
(1)onreadystatechange:綁定一個事件處理函數(shù)(監(jiān)聽器)氧急,該函數(shù)用來處理readystatechange事件。Ajax對象的readyState屬性發(fā)生改變毫深,比如從0到1吩坝,則會產(chǎn)生onreadystatechange事件。
(2)responseText:獲得服務(wù)器返回的文本數(shù)據(jù)
(3)responseXML:獲得服務(wù)器返回的Xml文檔
(4)status:獲得狀態(tài)碼
(5)readyState:返回Ajax對象與服務(wù)器通訊的狀態(tài)哑蔫,返回值是一個number類型的值钉寝,一共有5個值弧呐,分別是:
? ? ? ? ?<1>0:(未初始化)對象已經(jīng)建立,但是尚未進(jìn)行初始化(沒有調(diào)用open方法)
? ? ? ? ?<2>1:(初始化)對象已經(jīng)建立嵌纲,沒有調(diào)用send方法
? ? ? ? ?<3>2:(發(fā)送數(shù)據(jù))send方法已經(jīng)調(diào)用
? ? ? ? ?<4>3:(數(shù)據(jù)傳送中)已經(jīng)接受部分?jǐn)?shù)據(jù)
? ? ? ? ?<5>4:(響應(yīng)結(jié)束)Ajax對象已經(jīng)獲得了服務(wù)器返回的所有的數(shù)據(jù)
1.4編程步驟
(1)發(fā)送get請求
? ? ? ? ? ?step1:獲得Ajax對象俘枫,比如:varxhr=getXhr();//調(diào)用之前定義的函數(shù)
? ? ? ? ? step2:使用Ajax對象發(fā)送get請求:
? ? ? ? ? ? ? ? ? ? ? ?①調(diào)用xhr.open('get',check_username.do?username=chang&age=23,true);方法:建立與服務(wù)器之間的連接,三個參數(shù)依次為:請求方式逮走、請求資源路徑鸠蚪、請求是同步還是異步。true:表示異步請求(Ajax對象發(fā)送請求時师溅,用戶可以對當(dāng)前頁面作其他的操作茅信,不會銷毀頁面)。false:表示同步請求(Ajax對象發(fā)送請求時墓臭,瀏覽器會鎖定當(dāng)前頁面蘸鲸,用戶只能等待,不會銷毀頁面)窿锉。
? ? ? ? ? ? ? ? ? ? ?②xhr.onreadystatechange=func1();:綁定一個事件處理函數(shù)(監(jiān)聽器)
? ? ? ? ? ? ? ? ? ? ?③xhr.send(null);:發(fā)送請求參數(shù)酌摇,因為參數(shù)已經(jīng)寫在了請求資源路徑中,所以這里為null嗡载。
? ? ? ? ? ? step3:編寫服務(wù)器端的處理程序窑多,跟以前相比,有一點點改變鼻疮,就是一般不需要返回一個完整的頁面怯伊,只需要返回部分的數(shù)據(jù)。
? ? ? ? ? ? step4:編寫事件處理函數(shù)
? ? ? ? ? ? ? ? ? ? ? ? ? ?functionf1(){
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if(xhr.readyState==4){
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?var ? txt ?= ? ?xhr.responseText; ? dom操作……
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
(2)發(fā)送post請求
? ? ? ? ? ?step1:獲得Ajax對象判沟,比如:varxhr=getXhr();//調(diào)用之前定義的函數(shù)
? ? ? ? ? ?step2:使用Ajax對象發(fā)送post請求
? ? ? ? ? ? ? ? ? ? ? ?①xhr('post','check_username.do',true);:建立連接
? ? ? ? ? ? ? ? ? ? ? ?②xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');:發(fā)送一個content-type消息頭
? ? ? ? ? ? ? ? ? ? ? ③xhr.onreadystatechange=func1(); ? //綁定一個事件處理函數(shù)(監(jiān)聽器)
? ? ? ? ? ? ? ? ? ? ? ④xhr.send('username=chang'); ? ?//發(fā)送請求參數(shù)
? ? ? ? ? 注意事項:
? ? ? ? ? ? ? ? ? ?與get請求不同耿芹,請求參數(shù)要放到send方法里面。
? ? ? ? ? ? ? ? ? ?因為按照HTTP協(xié)議的要求挪哄,發(fā)送post請求時吧秕,應(yīng)該發(fā)送一個content-type消息頭,而Ajax對象在默認(rèn)情況下迹炼,不會發(fā)送這個消息頭砸彬,所以,需要調(diào)用setRequestHeader方法來添加斯入。
? ? ? ? ? ?step3:編寫服務(wù)器端的處理程序砂碉,跟以前相比,有一點點改變刻两,就是一般不需要返回一個完整的頁面增蹭,只需要返回部分的數(shù)據(jù)。
? ? ? ? ? ?step4:編寫事件處理函數(shù)
1.5編碼問題
(1)發(fā)送get請求
? ? ? ? 亂碼產(chǎn)生的原因:IE瀏覽器內(nèi)置的Ajax對象會使用“GBK”或“GB2312”對中文參數(shù)進(jìn)行編碼磅摹,而其他瀏覽器(Chrom滋迈、Firefox)內(nèi)置的Ajax對象會使用“utf-8”對中文參數(shù)進(jìn)行編碼霎奢。服務(wù)器端,默認(rèn)會使用“ISO-8859-1”去解碼饼灿。因為編碼與解碼所使用的字符集(編碼格式)不一致幕侠,所以,會出現(xiàn)亂碼問題碍彭。
? ? ? ?解決方法:
? ? ? ?step1:設(shè)置服務(wù)器使用指定的字符集去解碼晤硕。比如,可以修改Tomcat的server.xml配置(conf文件夾中)硕旗,添加URIEncoding="utf-8"(告訴服務(wù)器窗骑,對于所有的get請求,默認(rèn)使用“utf-8”去解碼)漆枚,修改之后重新啟動服務(wù)器。
? ? ? ?step2:使用encodeURI()函數(shù)(JS中內(nèi)置函數(shù))對請求地址進(jìn)行編碼抵知。encodeURI()函數(shù)會使用“utf-8”進(jìn)行編碼
(2)發(fā)送post請求
? ? ? ? ? ①亂碼問題產(chǎn)生的原因:所有瀏覽器(一般指三大瀏覽器:Chrom墙基、Firefox、IE)內(nèi)置的Ajax對象都會使用”utf-8”對中文參數(shù)進(jìn)行編碼刷喜,而服務(wù)器默認(rèn)情況下残制,會使用“ISO-8859-1”去解碼。
? ? ? ? ? ?注意事項:Firefox特殊掖疮,本應(yīng)是亂碼初茶,但能正常顯示。通過截取消息頭發(fā)現(xiàn)Firefox會在消息頭中自動添加"charset=utf-8"浊闪。
? ? ? ? ? ?②解決:服務(wù)器端添加:request.setCharacterEncoding("utf-8");
1.6Ajax的優(yōu)點
(1)頁面無刷新恼布,不打斷用戶的操作
(2)按照需要獲取數(shù)據(jù),客戶端(瀏覽器)與服務(wù)器之間的數(shù)據(jù)傳輸量大大減少
(3)是一種標(biāo)準(zhǔn)化的技術(shù)搁宾,不需要下載任何插件
1.7緩存問題(IE瀏覽器)
(1)發(fā)送get請求時
? ? ? ? ? IE瀏覽器(其他瀏覽器沒這個問題)內(nèi)置的Ajax對象會檢查請求地址是否訪問過折汞,如果訪問過,則不再向服務(wù)器發(fā)送請求盖腿。
(2)解決方式
? ? ? ? ? 方式一:在請求地址后面添加一個隨機(jī)數(shù)爽待,用于欺騙IE,例如:
? ? ? ? ? ? ? ? ? ? ? ? ? xhr.open('get','getNumber.do?'+Math.random(),true);
? ? ? ? ? 方式二:使用post方式發(fā)請求
Ajax的Get和Post的區(qū)別:
Get方式:用get方式可傳送簡單數(shù)據(jù)翩腐,但大小一般限制在1kb下鸟款,數(shù)據(jù)追加到url中發(fā)送(http的header傳送),也就是說茂卦,瀏覽器將各個表單字段元素及其數(shù)據(jù)按照url參數(shù)的格式附加在請求房中的資源路徑后面何什,另外最重要的一點事,它會被客戶端的瀏覽器魂村起來疙筹,那么別人就可以從瀏覽器的歷史記錄中讀取到客戶的數(shù)據(jù)富俄,因為禁炒,在某些情況下,get方法會帶來嚴(yán)重的安全性問題
Post方式:當(dāng)使用Post方式的時候霍比,瀏覽器把各表單字段元素及其數(shù)據(jù)作為HTTP消息的實體內(nèi)容發(fā)送給Web服務(wù)器幕袱,而不是作為url地址的參數(shù)進(jìn)行傳遞,使用POST方式傳遞的數(shù)據(jù)量要比GET方式傳送的數(shù)據(jù)量大得多
總之悠瞬,GET方式傳送數(shù)據(jù)量小们豌,處理效率高,安全性地浅妆,會被緩存望迎,但是POST卻不會
1.POST傳輸數(shù)據(jù)時,不需要在URL中顯示出來凌外,而GET方法要在URL中顯示
2.POST傳輸?shù)臄?shù)據(jù)量大辩尊,可以達(dá)到2MB,而GET方法由于受到URL長度的限制康辑,只能傳遞大約1024KB
3.POST是為了將數(shù)據(jù)傳送到服務(wù)器摄欲,GET就是為了從服務(wù)器獲取的數(shù)據(jù),而GET之所以也能傳送數(shù)據(jù)疮薇,只是用來設(shè)計告訴服務(wù)器胸墙,你到底需要什么樣的數(shù)據(jù)。POST的信息作為http請求的內(nèi)容按咒,而GET是在http頭部傳輸?shù)?/p>
在客戶端使用get請求時迟隅,服務(wù)器端使用Request.QueryString來獲取參數(shù),而客戶端使用post請求時励七,服務(wù)器端使用Request.From來獲取參數(shù)
Ajax是與服務(wù)器交換數(shù)據(jù)并且更新部分網(wǎng)頁的藝術(shù)智袭,在不重新加載整個頁面的情況下,有很多使用AJAX的應(yīng)用程序案例:開心網(wǎng)等