1. 程式人生 > >從零開始學 Web 之 Ajax(三)Ajax 概述,快速上手

從零開始學 Web 之 Ajax(三)Ajax 概述,快速上手

lan 技術分享 php 概述 由於 val asc logs 更新

大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新......

  • github:https://github.com/Daotin/Web
  • 微信公眾號:Web前端之巔
  • 博客園:http://www.cnblogs.com/lvonve/
  • CSDN:https://blog.csdn.net/lvonve/

在這裏我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,期間也會分享一些好玩的項目。現在就讓我們一起進入 Web 前端學習的冒險之旅吧!

技術分享圖片

一、Ajax 概述

Ajax 全稱:Asynchronous JavaScript and XML(異步 JavaScript 和 XML)。它不是一種新的編程語言,而是一種用於創建更好更快以及交互性更強的Web應用程序的技術。它可以在無需重新加載整個網頁的情況下,能夠更新部分網頁的技術。而傳統的網頁(不使用 AJAX)如果需要更新內容,必需重載整個網頁面。

還有為什麽叫異步呢?

因為在加載的時候,頁面的其他部分還是可以自由操作的,沒有出現卡死的狀態,所以是異步。

有很多使用 AJAX 的應用程序案例:新浪微博、Google 地圖、開心網等等。

在此之前,我們可以通過以下幾種方式讓瀏覽器發出對服務端的請求,獲得服務端的數據:

  • 地址欄輸入地址,回車,刷新
  • 特定元素的 href 或 src 屬性
  • 表單提交

這些方案都是我們無法通過或者很難通過代碼的方式進行編程(對服務端發出請求並且接受服務端返回的響應) 。

如果仔細觀察一個Form的提交,你就會發現,一旦用戶點擊“Submit”按鈕,表單開始提交,瀏覽器就會刷新頁面,然後在新頁面裏告訴你操作是成功了還是失敗了。如果不幸由於網絡太慢或者其他原因,就會得到一個404頁面。

這就是Web的運作原理:一次HTTP請求對應一個頁面。

如果要讓用戶留在當前頁面中,同時發出新的HTTP請求,就必須用JavaScript發送這個新請求,接收到數據後,再用JavaScript更新頁面,這樣一來,用戶就感覺自己仍然停留在當前頁面,但是數據卻可以不斷地更新。

最早大規模使用AJAX的就是Gmail,Gmail的頁面在首次加載後,剩下的所有數據都依賴於AJAX來更新。

用JavaScript寫一個完整的AJAX代碼並不復雜,但是需要註意: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);
                    }
                }
            };

1、創建對象

在IE6及以下的時候,是不支持 XMLHttpRequest 對象的,那麽與之對應寫法為:

var xhr = new ActiveXObject("Microsoft.XMLHTTP");

所以為了兼容性,上面的創建對象的方式改為:

var xhr = null;
if(window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
} else {
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
}

2、open 方法

第一個參數是請求的方式,是 get 請求還是 post 請求。一般取決後端開發的php文件裏面寫的是 get 還是 post。

第二個參數是需要請求的地址。如果是 get 請求,需要在地址後面加上 ? 進行連接操作,連接的是需要請求的你內容。(參考下面驗證用戶名示例),如果是 post 請求,只需要寫請求的地址就可以了,它的請求內容是寫在 send 中的。

第三個參數是同步或者異步,一般可以不寫,不寫默認異步,false:同步,true:異步。

3、send 方法

對於 get 方式,參數為 null;

對於 post 方式,參數為請求的數據。

var param = "username=" + uname; // 和 get 地址後面 ? 鏈接請求內容一致
shr.send(param);

對於 post 請求,還需要設置下請求頭(post請求才有)

// 僅僅針對 post 請求才有
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

4、onreadystatechange 回調函數

之所以是回調函數,這樣不會阻塞當前的操作,什麽時候服務器返回數據,什麽時候使用。這就是異步。

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 "用戶名可以使用!";
    }
?>

技術分享圖片

從零開始學 Web 之 Ajax(三)Ajax 概述,快速上手