0x00:什麼是Ajax?javascript
Ajax是Asynchronous Javascript And Xml 的縮寫(異步javascript及xml),Ajax是使用javascript在瀏覽器後臺操做HTTP和web服務器進行數據交換(用戶不知道也感受不出來,就跟桌面應用程序似的進行數據交互),它不會致使頁面從新加載,這樣纔有更好的用戶體驗。php
Ajax是基於如下開放標準:css
通俗的說就是使用了javascript(DOM)的XMLHttpRequest對象(ajax核心API也是瀏覽器的http API)及後續一系列的操做(發送和接收操做),接收來自服務器xml(json)等數據格式的數據,用html和css來顯示出來。因此它們只是組合出來的一種新的技術。html
歷史什麼的我就不介紹了。java
0x01:怎樣使用Ajax?web
001:實例化一個XMLHttpRequest對象ajax
var xhr = new XMLHttpReques();chrome
就是這麼簡單。通常不用考慮兼容性,若是你想讓每一用戶都能享受到ajax帶來的福利。你還要考慮咱們IE5,6的朋友(如今應該用的很少了吧,具體我也不知道);json
你能夠定義一個實例化這個對象的函數:跨域
function createXHR() { if(window.XMLHttpRequest) { return new XMLHttpRequest(); } else if(window.ActiveXObject) { return new ActiveXObject(Microsoft.XMLHTTP); } }
這就兼容一切瀏覽器了。
002:發送請求
實例化對象後,就要發送請求了,要使用XMLHttpRequest對象的open()和send()方法及可選setRequestHeader()方法(請求頭設置)。
首先來講open()方法。它能夠接受三個參數,第一個參數是要發送的請求的類型(即GET,POST等),第二個參數是請求的URL(網址)(即服務器上文件的地址,但不能跨域請求),第三個參數是一個布爾值(true表示異步,false表示同步)。
細節:
the first argument:第一個參數GET,POST等是不區分大小寫的,可是通用的作法是都用大寫。
那何時用GET,何時用POST呢?
GET簡單說就是向服務器請求查詢資源時用,請求不對服務器有任何反作用,是冪等的(即對同一url屢次請求應該返回相同的結果)
具體如下是GET請求的特色,你能夠根據這些特色來使用
1.GET請求的響應能夠被瀏覽器緩存
2.GET請求有長度限制(具體跟瀏覽器和服務器自身設置有關通常能夠2k-8k)
3.GET請求能夠在歷史記錄中查看,(若是發送了敏感數據,別人經過查看你的歷史記錄就能看見)
4.GET請求能夠保存爲書籤
5.GET請求只有請求頭,沒有主體,要設置查詢字符串參數,首先要進行編碼,而後把數據放在url後面,用?把地址和查詢參數隔開,
查詢參數之間用&隔開例如:www.123.com/aa.php?name=‘wy’l&id=001;url地址欄因此也不能發送敏感數據,用戶能看見了。
POST是向服務器發送要處理的數據時用
具體如下是POST請求的特色。
1.通常不對請求的數據的長度進行限制
2.瀏覽器不進行緩存文件、數據,沒法使用緩存文件等
3.數據在主體中,相對GET安全點,通常用戶看不見,要是用工具那就另說了,get可能形成CSRF攻擊
4.發送包含未知字符的用戶輸入時,POST 比 GET 更穩定也更可靠
根據這些特色你就知道該何時用GET和POST。
the second argument:第二個參數,須要注意的是,不能進行跨域請求。什麼是跨域呢,就是當兩個url中只要
其中一項不一樣就是跨域,協議,域名,端口不一樣就是跨域,具體以下截圖,看懂就明白了。
截圖來自:http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html
the third argument:第三個參數是能夠省略的,那就默認異步(true),異步和同步在不一樣的地方解釋會有不一樣,這裏是的意思是,同步的話會阻塞javascript的執行,就是說在調用send()方法後,瀏覽器就會在這個地方中止後面的代碼執行,一直到服務器響應,纔再往下執行後面的代碼,若是用異步的話,javascript就會在調用了send()方法後,不會等待服務器的響應,繼續執行下面的代碼,可是你也不能無論了吧,這裏就會說到下面要講的要進行事件監聽,當你服務器有響應了,我再去操做你的數據等操做。
說了半天也沒有說代碼是怎麼樣的:
//GET請求 xhr.open("GET","www.123.com/bb.php") xhr.open("GET","www.123.com/bb.php?a=2&b=3")//若是你要加上查詢數據的話 //POST請求 xhr.open("POST","www.123.com/aa.php")
在說send()方法以前還要說,請求頭的設置,若是是GET請求,這一步能夠沒有,可是要是POST表單編碼請求必須要設置「Content-Type」頭來指定請求的主題的MIME類型(就是告訴服務器我給的是什麼類型的數據)值爲:application/x-www-form-urlencoded。它的值還有值能夠是application/json,text/plain,text/html,text/xml等,有時候XMLHttpRequest對象會自動識別你發送數據的類型,因此你也能夠沒有,可是最好設置上。其餘的若是你有特殊須要你就設置;有一些頭是你不能本身設置,如Content-Length,Date,Referer,User-Agent等,除了這些你均可以本身設置,不須要的瀏覽器就發送本身默認的請求頭。若是對相同的頭調用setRequestHeader()屢次,新值不會取代以前的值,而是HTTP請求頭包含這個頭的多個副本或者這個頭將指定多個值。
設置請求頭用setRequestHeader()方法。必定要注意了,必須在調用open()方法以後,而且在調用send()方法以前調用setRequestHeader()方法。
post用:
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");//表單編碼的請求
如今真是說send()方法。先說GET下的send(),
xhr.send();//能夠這樣 xhr.send(null);//也能夠這樣,傳遞一個null,最好設置爲null,說有些瀏覽器不設置爲null會報錯,因此推薦這樣
POST:
xhr.send(msg)//請求的主體要發送內容
以後一次請求就這樣被髮送到服務器了,接下來就等着響應數據了,來進一步進行操做了。
003:等待響應
可使用XMLHttpRequest對象的一些屬性和方法來檢測服務器的響應。
首先說readyState屬性和readystatechange事件。
redayState屬性表示請求或響應過程處於當前的什麼階段了,它是用一個整數表示的0-4。我看見關於這個狀態的每一個整數表明的什麼狀態,說的稍微有點混亂或者說不太明確。我就測試了一下post下的狀況,先上測試代碼:
window.addEventListener("load",function() { var request = new XMLHttpRequest(); console.log("初始化對象時--" + request.readyState);//0 request.onreadystatechange = function() { console.log("事件--" + request.readyState);//打印每次觸發事件時readyState的狀態 console.log("服務器--" + request.status); if(request.readyState === 2) { console.log(request.getResponseHeader("Content-Type")); } if(request.readyState === 3) { console.log(request.responseText); } if(request.readyState === 4 && request.status == 200) { console.log(request.getResponseHeader("Content-Type")); // console.log(JSON.parse(request.responseText)); console.log(request.responseText); } } console.log("調用open以前--" + request.readyState);//0 console.log("服務器--" + request.status); request.open("POST","./test.php",true); console.log("調用open以後--" + request.readyState);//1 console.log("服務器--" + request.status); request.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8"); console.log("設置頭以後--" + request.readyState);//1 console.log("服務器--" + request.status); request.send('aa="aadfd"'); console.log("調用send以後" + request.readyState);//1 console.log("服務器--" + request.status); },false);
<?PHP
header("Content-Type:application/json");//設置響應頭的,由於以前測試忘記了就沒有刪除,因此下面截圖裏纔有application/json;這裏沒有必要有,只是我測試完了纔看見。 echo $_POST['aa']; ?>
chrome截圖: IE截圖
你能夠對照着這張截圖看你就明白了,到底這個過程是怎麼樣的?其實你也不須要太瞭解這個過程,咱們只對readyState等於4感興趣。
能夠發如今chrome,firefox,opera下的測試結果是,在你實例化XMLHttpRequest對象後,這個狀態是0,當你調用了open()方法後這個狀態變爲了1,這時會觸發一個readystatechange事件,你在設置頭的時候,這個狀態仍是1,在你調用send()方法時,這個狀態仍是1,接下來就是靠readystatechange事件來監聽了,它會被再觸發三次,當這個狀態變爲2時,就接收到了響應頭信息了,當變爲3的時候就接收到響應主體了,當4的時候那就響應完成了。
IE稍微有點不一樣就是在在設置完頭以後,還要觸發一次readystatechange事件,其餘的都相同
總結readyState值
常量 | 值 | 含義 |
UNSENT | 0 | open()還沒有調用 |
OPENED | 1 | open()已經調用 |
HEADERS_RECEIVED | 2 | 接收到頭信息 |
LOADING | 3 | 接收到響應主體(內容) |
DONE | 4 | 響應完成 |
readystatechange事件就是在readyState屬性值每次變化的時候觸發。要是同步的就不須要監聽這個事件。
接下來就說說XMLHttpRequest對象的這四個屬性:responseText,responseXML,status,statusText,
responseText:得到字符串形式的響應數據(只要不是xml格式的就用這個);
responseXML:得到 XML 形式的響應數據;
status:響應的Http狀態;例如200.(這個與readyState的對應關係能夠看上面的截圖)
statusText:響應的HTTP狀態說明,例如ok,其實和status是一個意思,只不過是一個用數字說明,一個用文本說明罷了,200=>ok(這個只有readyState爲2,3,4時有值);
最基礎的都介紹完了,咱們再來幾個完整測試demo。
GET方式:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- <meta http-equiv="X-UA-Compatible" content="IE=edge"> --> <title>php1</title> <script type="text/javascript"> window.addEventListener("load",function() { var btn = document.getElementById("btn"); var content = document.getElementById("content"); btn.addEventListener("click",function() { var request = new XMLHttpRequest(); request.onreadystatechange = function() { if(request.readyState === 4 && request.status == 200) { // console.log(JSON.parse(request.responseText)); content.innerHTML = request.responseText; } } request.open("GET","./test.php",true); // request.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8"); request.send(null); }); },false); </script> </head> <body> <input type="button" value="點我" id="btn"> <h2>下面是點擊後的內容:</h2> <p id="content"></p> </body> </html>
php:
<?php echo "hello!"; ?>
點擊前:
點擊後
要是添加查詢參數時,只須要修改open()方法的參數;
request.open("GET","./test.php?id=3&a=5",true);
php
<?php echo "你給個人東西是:<br>"; echo 'id是:'.$_GET['id'],"<br>"; echo "a是:".$_GET['a'],"<br>"; if($_GET['id']) { echo 'This is my respone!'; } ?>
點擊後:
POST 方式:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- <meta http-equiv="X-UA-Compatible" content="IE=edge"> --> <title>php1</title> <script type="text/javascript"> window.addEventListener("load",function() { var btn = document.getElementById("btn"); var text = document.getElementById("text"); var content = document.getElementById("content"); btn.addEventListener("click",function() { var msg = "id=" + text.value; console.log(msg); var request = new XMLHttpRequest(); request.onreadystatechange = function() { if(request.readyState === 4 && request.status == 200) { var obj = JSON.parse(request.responseText) if(obj['name']){ content.innerHTML = 'name:' + obj['name'] + '<br>' + 'age:' + obj['age']; } else { content.innerHTML = "沒有這我的的信息"; } } } request.open("POST","./test.php",true); request.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8"); request.send(msg); }); },false); </script> </head> <body> <label>請輸入身份id:<input type="text" id="text"></label> <input type="button" value="發送" id="btn"> <h2>下面是點擊後的內容:</h2> <p id="content"></p> </body> </html>
php代碼:
<?php header("Content-Type:application/json"); if($_POST['id'] == 001) { echo '{"name":"wyl","age":22}'; } else { echo '{}'; } ?>
輸入:001前:
輸入001,點擊後:
輸入其餘字符點擊後:
返回JSON格式的數據記得要用JSON.parse()解析;
POST的send()也能夠不傳遞數據。
還有其餘類型數據格式的請求或者響應的,之後有時間再介紹。
到此處最基本的東西應該就這些了。
00x2:XMLHttpRequest level 2:
在HTML5來臨的時候,w3c開始將這個XMLHttpRequest對象歸入標準中,由於之前就存在了這個對象,如今只是更新了,因此就叫2級XMLHttpRequest;
出現新的版本必定是老的版本有不足:
有如下幾點不足:
1.之前只能傳輸文本數據,不能用來讀取和上傳二進制文件(好比圖片);
2.接收和傳遞數據時,沒有進度信息,只能知道是否傳遞完成;
3.不能進行跨域請求
新版本(XMLHttpRequest 2)的新特性:
1.能夠設置HTTP的請求時限;
2.可使用FormDate對象管理表單數據
3.能夠上傳文件
4.能夠進行跨資源共享(跨域)CORS;
5.有更豐富的進度事件的API
要是介紹完,篇幅太長了,我本身都不看完,都看煩了,有空着再介紹;
參考資料:
犀牛書;紅寶書;
http://www.cnblogs.com/skylar/p/ajaxCORS.html
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
http://www.w3school.com.cn/ajax/ajax_intro.asp
http://javascript.ruanyifeng.com/bom/ajax.html
以上是本身結合了不少博客還有書籍總結的,僅表明我的對知識的理解和見解!若有不對的或者不許的地方,歡迎評論指正!