天天看點

Ajax探究和原生Ajax封裝

作者:Java小陳

什麼是Ajax?

Ajax 是一種技術方案,不是新技術。它依賴現有的CSS/HTML/Javascript,其中最核心的是XMLHttpRquest對象。

Ajax 請求步驟

  1. 建立 XMLHttpRequest 對象
  2. 準備發送請求 open()
  3. 發送請求資料 send()
  4. 請求傳回的回調函數 onreadystatechange = function(){}

Ajax步驟詳解

  1. 建立 XMLHttpRequest 對象

    var xhr = new XMLHttpRequest()

  2. 準備發射資料的 open() 方法

    文法:xhr.open("請求類型","url位址","是否異步")

    例如:xhr.open("get","http://127.0.0.1/index.php?username=123&sex=1",true) xhr.open("post","http://127.0.0.1/index.php?login.php",true)

  3. send() 發送請求的資料
  • post: send(data)
  • get: send()

    因為 get 請求發送的資料實際上是拼接在位址欄中,是以發送的資料為空。

  1. 回調函數 onreadystatechange 屬性指向一個回調函數

    當頁面加載狀态發生改變,xhr 的 readystate 屬性就會發生改變,然後 onreadystatechange 指向的回調函數就會自動被調用。

    例:

<script type="text/javascript">
        let xhr = new XMLHttpRequest();
        xhr.open("get","http://a.itying.com/api/productlist",true);
        xhr.send();
        if(xhr.readyState == 4 && xhr.status == 200) {
                console.log(xhr.response);
        }
    </script>
           

readyState 狀态值

是指運作AJAX所經曆過的幾種狀态,無論通路是否成功都将響應的步驟,可以了解成為AJAX運作步驟

0 - 4 的狀态變化:

  • 0: 請求未初始化
  • 1: 伺服器連接配接已建立
  • 2: 請求已接收
  • 3: 請求進行中
  • 4: 請求已完成且響應已就緒

status 狀态碼

是 XMLHttpRequest 對象的一個屬性,表示響應的HTTP狀态碼

狀态碼分五大類:

  • 1xx:資訊響應類,表示接收到請求并且繼續處理
  • 2xx:處理成功響應類,表示動作被成功接收、了解和接受
  • 3xx:重定向響應類,為了完成指定的動作,必須接受進一步處理
  • 4xx:用戶端錯誤,客戶請求包含文法錯誤或者是不能正确執行
  • 5xx:服務端錯誤,伺服器不能正确執行一個正确的請求

XMLHttpRquest相容

版本的 Internet Explorer(ie5 和 ie6) 使用 ActiveX 對象:

let xhr = new ActiveXObject("Microsoft.XMLHTTP")

請求逾時 timeout 和 逾時監聽 ontimeout

  1. timeout 屬性值為一個整數,機關為 ms (毫秒),用來設定請求發送後等待接收響應的時間。如果在設定時間内未能接收到後端響應的資料,則被認為請求逾時,則執行 ontimeout
  2. ontimeout() 是等待逾時後,自動執行的回調方法

    例:

let xhr = new XMLHttpRequest();
xhr.timeout = 60000;
xhr.ontimeout = function() {
      console.error("Time Out !")
}           

封裝原生的 Ajax

封裝思路:請求方式,請求位址,請求資料,回調函數

将請求的資料格式化成拼接的資料

/**
         * jsonData 的格式:
         * {
         *   url:       請求位址
         *   method:    請求類型
         *   data:      請求資料
         *   isAsync    是否異步
         *   success    成功的回調函數
         *  }
         * */
        function $ajax(jsonData) {
            let formatData = "";
            let xhr;
            // 相容低版本ie
            if(window.XMLHttpRequest) {
                xhr = new XMLHttpRequest()
            } else {
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
            // 格式化資料為 key1=value1&key2=value2 的格式
            if(jsonData.data) {
                let str = "";
                let arr = [];
                for(let key in jsonData.data) {
                    str = `${key}=${jsonData.data[key]}`
                    arr.push(str);
                }
                formatData = arr.join("&");
            }
            // get請求
            if(jsonData.method.toLowerCase() == "get") {
                xhr.open('get', jsonData.url + "?" + formatData, jsonData.isAsync);
                xhr.send()
            // post請求
            } else if(jsonData.method.toLowerCase() == "post") {
                xhr.open('post', jsonData.url, jsonData.isAsync);
                xhr.setRequestHeader('Contenttype','application/x-www-form-urlencoded;charset=utf-8');
                xhr.send(formatData);
            }
            // 狀态值和狀态碼對應上後 執行成功的回調函數
            xhr.onreadystatechange = function() {
                if(xhr.readyState == 4 && xhr.status == 200) {
                    jsonData.success(xhr.response);
                } 
            }
        }
           

具體使用案例:

$ajax({
                url: "http://127.0.0.1:8082/process_get",
                method: "get",
                data: {
                    myname: myname,
                    myage: myage
                },
                isAsync: true,
                success: function(res) {
                    console.log("successRes:", res);
                }
            })
        }
           
Ajax探究和原生Ajax封裝