曾經有一段時期,由於開發人員對JavaScript的濫用致使其遭受了一段時間的冷門時期,不被你們看好,後來,到了2005年,Google公司的不少技術都是用了ajax以後,JavaScript才又火熱了起來,能夠說,是Ajax拯救了JavaScript,就目前來講,熟練使用Ajax已經成爲了全部web開發人員必須掌握的技能。那麼Ajax又是什麼呢? 它的做用是什麼呢?javascript
Ajax即Asynchronous JavaScript +XML的簡寫,這一技術可以向服務器請求額外的數據而無需卸載頁面,會帶來更好地用戶體驗。Ajax的核心是XMLHttpRequest對象(簡稱XHR,這一對象受到chrome、safari、FF、opera等主流瀏覽器的支持),這是由微軟首先引入的一個特性,IE 瀏覽器(5和6)使用 ActiveXObject,後來瀏覽器提供商都提供了相同的實現。XHR對象的存在,意味着當用戶點擊以後,沒必要刷新頁面也能夠從後臺取得新數據,也就是說,能夠試用XHR對象取得新數據,而後經過DOM方式將新數據插入到頁面中,達到對網頁的某部分進行更新的效果。值得注意的是:雖然,Ajax中包含了xml,可是咱們在無需刷新頁面就獲得的數據不必定是xml數據,好比能夠是文本數據或者JSON數據。php
上面講到,Ajax的核心是XMLHttpRequest對象,那麼咱們如何建立一個XMLHttpRequest對象呢?html
首先,咱們應當知道:全部瀏覽器都支持XMLHttpRequest對象,其中IE5和IE6使用ActiveXObject對象。而且如今全部瀏覽器(IE7+、FireFox、Chrome、Safari以及Opera)均內建了XMLHttpRequest對象。因而建立XMLHttpRequest對象的語法是:java
var xhr = new XMLHttpRequest();
剛剛提到老版本的Internet Explorer(IE5和IE6)使用的是ActiveXObject對象,因此語法是:web
var axo = new ActiveXObject("Microsoft.XMLHTTP");
注意:其中傳入的「Microsoft.XMLHTTP」是不能改變的。ajax
因而,爲了應對全部的現代瀏覽器(包括IE5和IE6),請首先檢查是否支持XMLHttpRequest對象:若是支持,則建立XMLHttpRequest對象;若是不支持,則建立ActiveXObject對象:chrome
var xmlHttp=null; if(window.XMLHttpRequest) { xmlHttp=new XMLHttpRequest(); } else { xlmHttp=new ActiveXObject("Microsoft.XMLHTTP"); }
關於這個應對全部現代瀏覽器的代碼應當注意:跨域
上面兩部分,咱們介紹XHR對象是什麼以及怎麼建立,這一部分我將談一談XHR對象的用法。瀏覽器
⑴.open()方法緩存
既然XHR是一個對象,那麼它就必定有本身的屬性和方法。在使用XHR對象時,要調用的第一個方法是open()。它接受3個參數:
(補充:咱們不推薦使用async=false,由於這樣JavaScript會等到服務器響應就緒才繼續進行,若是服務器繁忙或緩慢,那麼應用程序會掛起或中止)
舉例以下:
xhr.open("get","example.php",true);
此時,這段代碼會啓動一個針對example.php的GET請求。注意:open()方法並不會真正的發送請求而只是啓動一個請求以備發送。那麼怎麼才能發送特定的請求呢,這是就要用到send()方法了。
⑵.send()方法
剛剛說到open()方法,只是開啓(open),尚未發送,而send纔是真正地發送。它接受一個參數:
注意:若是不須要經過請求主體發送數據,則必須傳入null。通常get請求不須要傳入參數,而對於post請求,若是須要像 HTML 表單那樣 POST 數據,請使用 setRequestHeader() 來添加 HTTP 頭。而後在 send() 方法中規定您但願發送的數據。這一部分會詳細介紹,下面舉一個簡單例子:
xhr.open("get","example.php",true); xhr.send(null);
(3).XHR對象的幾個屬性
經過send()發送以後,會接受到響應,響應的數據會自動填充XHR對象的屬性。主要有如下幾種:
在接收到響應後,通常是先檢查status屬性,來肯定響應是否成功返回,通常狀態代碼200表示成功(以2開頭即表示成功),這是responseText就能夠被訪問了。而狀態代碼爲304表示請求的資源並無被修改,能夠直接使用瀏覽器中緩存的版本,所以這種響應也是有效的。因而能夠經過下面的代碼檢測這兩種狀態:
xhr.open("get","example.php",false); xhr.send(null); if((xhr.status>=200&&xhr.status<300)||xhr.status==304){ alert(xhr.responseText); }else{ alert("Request waw unseccessful:"+"xhr.status"); }
XHR對象的readystate屬性
使用Ajax咱們固然仍是但願發送異步請求的:若是發送同步請求,那麼一旦網卡住了,這個頁面就不會有任何反應而是繼續等待響應,可是發送異步請求,即便網卡住,也不用擔憂,由於它是異步的。而readystate屬性能夠檢測到請求/響應過程的當前活動階段。它有5個取值,分別以下:
關鍵:只要readystate的值改變(好比從0變爲1,從1變爲2等等),那麼每次地改變都會觸發readystatechange事件。而且能夠經過這個時間檢測每次狀態變化後的readystate的值。當值爲4是最重要的,由於這事全部的數據已經準備就緒。看一個例子:
var xhr=new XMLHttpRequest(); xhr.open("get","example.php",false); xhr.onreadystatechange=function(){ if(readyState==4){ if((xhr.status>=200&&xhr.status<300)||xhr.status==304){ alert(xhr.responseText); }else{ alert("Request waw unseccessful:"+"xhr.status"); } } }; xhr.send(null);
注意如下幾點:
(4).abort()方法
在接受到響應以前,咱們還可使用abort()方法來取消異步請求,以下所示:
xhr.abort();
在調用了這個方法以後,XHR對象會中止觸發事件,並且也再也不容許訪問任何與響應有關的對象屬性。
(5)setRequestHeader()方法、getResponseHeader()方法、getAllResponseHeader()方法在第四部分介紹完以後講解
由於使用Ajax和後臺交互,那麼就必定離不開http協議了。而HTTP請求和響應都會帶有相應的頭部信息。
在默認狀況下,在發送XHR請求的同時,還會發送如下頭部信息。
下面這張圖片是個人chrome瀏覽器開發者工具下的network中截屏所得,你們能夠對照參考:
咱們還能夠經過setRequestHeader()方法來設置自定義的請求頭部信息。這個方法接收兩個參數:頭部字段的名稱和頭部字段的值。而且咱們必須在open()方法以後,在send()方法以前來調用setRequestHeader()方法。舉例以下:
var xhr=new XMLHttpRequest(); xhr.open("get","example.php",true); xhr.setRequestHeader("myHeader","myValue"); xhr.send(null);
這裏只須要注意:這裏傳入的頭部字段的名稱最好是自定義的,而不要使用瀏覽器正常發送的字段名稱,不然有可能會影響瀏覽器的響應。(由於有的瀏覽器容許開發人員重寫默認的頭部信息,而有的瀏覽器是不容許開發人員重寫默認的頭部信息的)。
除了能夠爲請求頭部增長自定義的頭部字段,咱們還能夠獲取頭部字段。咱們能夠調用XHR對象的getResponseHeader()方法並傳入一個頭部字段名稱,即可以得到響應頭部信息。還能夠調用XHR對象的getAllResponseHeaders()方法取得一個包含全部頭部信息的長字符串。
以下所示:
var myHeader=xhr.getResponseHeader("myHeader"); var allHeaders=xhr.getAllResponseHeaders();
get請求用於向服務器查詢某些信息。注意,查詢字符串(名稱/值對)是在 GET 請求的 URL 中發送的。 可是,有時候可能會出現問題,即查詢字符串的格式有問題。查詢字符串的每一個參數的名稱和值都必須使用encodeURIComponent()進行編碼,而後才能放到URL的末尾;並且全部的名值對都必須用&分隔。以下所示:
xhr.open("get","example.php?name1=value1&name2=value2",true);
而下面的這個函數能夠輔助向現有的URI的末尾添加查詢字符串:
function addURIParam(url,name,vaule){ url+=(url.indexOf("?")==-1?"?":"&"); url+=encodeURIComponent(name)+"="+encodeURIComponent(value); return url; } var url="example"; url=addURIParam(url,"name","zzw"); url=addURIParam(url,"sex","male"); xhr.open("get",url,false);
實際上,函數中的第一句是先判斷url後面有沒有查詢字符串,若是沒有,就添加?,若是有,就添加&,所以,最終的url爲"example.php?name=zzw&sex=male"。
另外,對於get請求須要注意:
POST請求的使用頻率僅次於GET請求,一般用於向服務器中發送應該被保存的數據。請注意,查詢字符串(名稱/值對)是在 POST 請求的 HTTP 消息主體中發送的。而GET請求卻不是這樣的。POST請求的主體能夠包含不少的數據,並且格式不限。
默認狀況下,服務器對post請求和提交web表單的請求不會一視同仁,所以,咱們能夠試用XHR對象和模仿表單提交:首先將Content-Type頭部信息設置爲application/x-www-form-urlencoded,也就模仿成了表單提交時的內容類型(贊一個!)。接着須要在以適當的格式建立一個字符串,post數據的格式和查詢字符串格式相同,若是須要將頁面中表單的數據序列化,在經過XHR發送到服務器,那麼就要使用serialize()函數來建立這個字符串。下面舉兩個例子:
xhr.open("POST","example.php",true); xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xhr.send("fname=Bill&lname=Gates");
這裏咱們沒有將字符串序列化。
xhr.open("POST","example.php",true); xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); var form=document.getElementById("user-info"); xhr.send(serialize(form));
這裏咱們使用serialize()函數進行了序列化。
另外,對於post請求須要注意:
講過了POST請求和GET請求,那麼它們之間的區別是什麼呢?
經過XHR實現Ajax通訊的一個主要限制,來源於跨域安全策略,又稱爲同源策略。那麼什麼是同源策略呢?
同源策略,它是由Netscape提出的一個著名的安全策略,默認狀況下,XHR對象只能訪問與包含他的頁面位於同一個域中的資源,這種安全策略能夠預防某些惡意行爲。如今全部支持JavaScript的瀏覽器都會使用這個策略,這種安全策略能夠預防某些惡意行爲,好比,A網站是一家銀行,若是用戶登錄了之後,其餘的網站能夠讀取A網站的Cookie,那麼其餘網站就能夠隨心所欲了。可是,實現合理的跨域請求對開發某些瀏覽器的應用程序也是相當重要的。後續的文章我會介紹跨域資源共享的知識。這裏僅介紹同源策略。
所謂同源是指:協議、域名和端口相同。
舉例說:http://www.cnblogs.com/dir/page.html這個網址。
協議:http://
域名:www.cnblogs.com
端口:80(默認端口能夠省略)。
對於這個網址的同源狀況以下:
1.原生ajax的使用
在控制檯的結果以下所示:
2. jQuery中ajax的使用
本身選擇的路、跪着也要把它走完。