你們好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新......php
- github:https://github.com/Daotin/Web
- 微信公衆號:Web前端之巔
- 博客園:http://www.cnblogs.com/lvonve/
- CSDN:https://blog.csdn.net/lvonve/
在這裏我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,期間也會分享一些好玩的項目。如今就讓咱們一塊兒進入 Web 前端學習的冒險之旅吧!html
Ajax 全稱:Asynchronous JavaScript and XML(異步 JavaScript 和 XML)。它不是一種新的編程語言,而是一種用於建立更好更快以及交互性更強的Web應用程序的技術。它能夠在無需從新加載整個網頁的狀況下,可以更新部分網頁的技術。而傳統的網頁(不使用 AJAX)若是須要更新內容,必需重載整個網頁面。前端
還有爲何叫異步呢?git
由於在加載的時候,頁面的其餘部分仍是能夠自由操做的,沒有出現卡死的狀態,因此是異步。github
有不少使用 AJAX 的應用程序案例:新浪微博、Google 地圖、開心網等等。ajax
在此以前,咱們能夠經過如下幾種方式讓瀏覽器發出對服務端的請求,得到服務端的數據:數據庫
這些方案都是咱們沒法經過或者很難經過代碼的方式進行編程(對服務端發出請求而且接受服務端返回的響應) 。編程
若是仔細觀察一個Form的提交,你就會發現,一旦用戶點擊「Submit」按鈕,表單開始提交,瀏覽器就會刷新頁面,而後在新頁面裏告訴你操做是成功了仍是失敗了。若是不幸因爲網絡太慢或者其餘緣由,就會獲得一個404頁面。後端
這就是Web的運做原理:一次HTTP請求對應一個頁面。瀏覽器
若是要讓用戶留在當前頁面中,同時發出新的HTTP請求,就必須用JavaScript發送這個新請求,接收到數據後,再用JavaScript更新頁面,這樣一來,用戶就感受本身仍然停留在當前頁面,可是數據卻能夠不斷地更新。
最先大規模使用AJAX的就是Gmail,Gmail的頁面在首次加載後,剩下的全部數據都依賴於AJAX來更新。
用JavaScript寫一個完整的AJAX代碼並不複雜,可是須要注意:AJAX請求是異步執行的,也就是說,要經過回調函數得到響應。
使用 Ajax 的過程能夠類比日常咱們訪問網頁過程 :
// 1. 建立一個 XMLHttpRequest 類型的對象 —— 至關於打開了一個瀏覽器 var xhr = null; if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } // 2. 打開與一個網址之間的鏈接 —— 至關於在地址欄輸入訪問地址 xhr.open("get", "checkusername.php?username=" + uname, true); // 3. 經過鏈接發送一次請求 —— 至關於回車或者點擊訪問發送請求 xhr.send(null); // 僅僅針對 post 請求 //xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // 4. 指定 xhr 狀態變化事件處理函數 —— 至關於處理網頁呈現後的操做 xhr.onreadystatechange = function () { if (this.readyState == 4) { if (this.status == 200) { console.log(this.responseText); } } };
在IE6及如下的時候,是不支持 XMLHttpRequest 對象的,那麼與之對應寫法爲:
var xhr = new ActiveXObject("Microsoft.XMLHTTP");
因此爲了兼容性,上面的建立對象的方式改成:
var xhr = null; if(window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else { xhr = new ActiveXObject("Microsoft.XMLHTTP"); }
第一個參數是請求的方式,是 get 請求仍是 post 請求。通常取決後端開發的php文件裏面寫的是 get 仍是 post。
第二個參數是須要請求的地址。若是是 get 請求,須要在地址後面加上 ? 進行鏈接操做,鏈接的是須要請求的你內容。(參考下面驗證用戶名示例),若是是 post 請求,只須要寫請求的地址就能夠了,它的請求內容是寫在 send 中的。
第三個參數是同步或者異步,通常能夠不寫,不寫默認異步,false:同步,true:異步。
對於 get 方式,參數爲 null;
對於 post 方式,參數爲請求的數據。
var param = "username=" + uname; // 和 get 地址後面 ? 連接請求內容一致 shr.send(param);
對於 post 請求,還須要設置下請求頭(post請求才有)
// 僅僅針對 post 請求才有 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
之因此是回調函數,這樣不會阻塞當前的操做,何時服務器返回數據,何時使用。這就是異步。
status:服務器返回的狀態碼
this.status == 200:表示響應成功;404 表示沒有找到請求的資源;500 表示服務器端錯誤。
readyState:
xhr對象的狀態改變時,readyState的值也會相應的改變。具體數值的含義見下表:
readyState | xhr狀態 | 說明 |
---|---|---|
0 | UNSENT | 代理(xhr)被建立,但還沒有調用 open 方法 |
1 | OPENED | open 方法已經被調用,創建了鏈接 |
2 | HEADERS_RECEIVED | send 方法已經被調用,已經能夠獲取狀態行和響應頭 |
3 | LOADING | 響應體下載中,responseText 屬性可能已經包含部分數據 |
4 | DONE | 響應體下載完成,能夠直接調用 responseText 獲取數據 |
詳細解析代碼:
var xhr = new XMLHttpRequest(); console.log(xhr.readyState); // => 0 // 初始化 請求代理對象 xhr.open('GET', 'time.php'); console.log(xhr.readyState); // => 1 // open 方法已經調用,創建一個與服務端特定端口的鏈接 xhr.send(); xhr.addEventListener('readystatechange', function () { switch (this.readyState) { case 2: // => 2 // 已經接受到了響應報文的響應頭 // 能夠拿到頭 // console.log(this.getAllResponseHeaders()) console.log(this.getResponseHeader('server')); // 可是尚未拿到體 console.log(this.responseText); break; case 3: // => 3 // 正在下載響應報文的響應體,有可能響應體爲空,也有可能不完整 // 在這裏處理響應體不保險(不可靠) console.log(this.responseText); break; case 4: // => 4 // 一切 OK (整個響應報文已經完整下載下來了) // 這裏處理響應體 console.log(this.responseText); break; } });
當 readyState == 2 時,只獲取到數據頭,這時不能使用 responseText 獲取,而是用 getResponseHeader 來獲取數據頭信息。
當 readyState == 3 時,可能已經獲取部分數據體,可是處理數據是不可靠的,因此通常通常咱們都是在 readyState 值爲 4 時,執行響應的後續邏輯 。
其實,當 onreadystatechange 執行時 而且 readyState == 4 的時候,在 HTML5 中有了更加便捷的寫法:
xhr.onload = function () { console.log(this.readyState); // 4 console.log(this.readyState); }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div> <h1>用戶註冊</h1> 用戶名: <input type="text" name="username"> <input type="button" value="驗證用戶名" id="btn"> <span></span> <br> 密碼: <input type="password" name="passwd"> <br> <input type="submit" value="註冊提交"> </div> <script> var spanObj = document.getElementsByTagName("span")[0]; document.getElementById("btn").onclick = function () { // 獲取用戶名 var uname = document.getElementsByName("username")[0].value; // 發送給服務器處理 var xhr = new XMLHttpRequest(); xhr.open("get", "checkusername.php?username=" + uname, true); xhr.send(null); xhr.onreadystatechange = function () { if (this.readyState == 4) { spanObj.innerText = xhr.responseText; if (xhr.responseText == "用戶名已存在!") { spanObj.style.color = "red"; } else { spanObj.style.color = "green"; } } }; }; </script> </body> </html>
後臺 PHP代碼:
<?php $user = $_GET["username"]; if($user == "lvonve") { // 這裏僅僅只判斷一個用戶名,其實是由數據庫提供 echo "用戶名已存在!"; } else { echo "用戶名可使用!"; } ?>