ajax發送異步請求從入門到精通

ajax發送異步請求

一、什麼是ajax

  AJAX = Asynchronous JavaScript and XML(異步的 JavaScript 和 XML),AJAX 是與服務器交換數據並更新部分網頁的藝術,在不重新加載整個頁面的情況下。
也就是說ajax和我們在瀏覽器地址欄,或者通過form表單發送請求一樣,ajax也可以發送請求,但是二者有很大的不同,ajax不用刷新界面,發送異步請求。


二、發送ajax get請求的步驟

 ① 創建異步對象 
var  xhr =new XMLHttpRequest();

 ② 設置URL
xhr.open('get',"index.php",true);
// 參數1:發送請求方式
// 參數2:請求的url地址
// 參數3: 請求是同步還是異步。true爲異步,默認爲true

③ 發送請求 

xhr.send();

 ④ ⑤ 監聽事件-->處理響應

 xhr.onreadystatechange = function () {
   // onreadystatechange 可以監聽如下狀態:
   //0:請求未初始化    1:服務器連接已經建立   2:請求已接收  3:請求處理中   4:請求已完成,且響應已就緒
        //判斷當前狀態是否已經響應完畢,處理響應
        if(xhr.readyState ==4){
            // 排除訪問可能出現的問題,通過服務器返回的狀態碼來排除,304代表訪問緩存
            if (xhr.status >=200 && xhr.status <300 ||xhr.status==304){
                console.log("請求成功!");
            }
            else {
                console.log("請求失敗!");
            }
        }
    }


三、處理ie 發送ajax的兼容問題


由於ie低版本瀏覽器中沒有XMLHttpRequest對象,而是ActiveXObject對象
處理方式:
//處理兼容問題
        var xhr;
        if(window.XMLHttpRequest){
            xhr =new XMLHttpRequest();
        }
        else {
            xhr = new ActiveXObject('Microsoft.XMLHTTP');
        }


四、封裝ajax的 get請求 (初級)


/*傳參的格式 封裝 將傳入的對象,轉爲url 拼接的方式*/
function json2Str(data) {
           //定義數組
           var arr = [];
           //遍歷傳入的對象
           for (var key in data){
               //將json轉爲數組
               arr.push(key+'='+data[key]);
               console.log(arr);
           }
           //將數組轉爲固定格式的字符串
         return  arr.join('&'); //取出數組中的每一項,然後用&符號連接
       }
   function ajaxGet(url,data,success,error) {
             //封裝get請求
             var xhr;
             if (XMLHttpRequest){
                 xhr = new XMLHttpRequest();
             }
             else {
                 xhr = new ActiveXObject("Microsoft.XMLHTTP");
             }
             xhr.open("get",url+'?'+data,true);
             xhr.send();
             xhr.onreadystatechange = function () {
                 if (xhr.readyState ==4){
                     if (xhr.status >=200 && xhr.status <300 ||xhr.status ==304){
                         success(xhr.response);
                     }
                     else {
                         error(xhr.status);
                     }
                 }
             }
         }
   ajaxGet('01-get.php',json2Str(data),function (res) {
             console.log(res);
         },function (code) {
             console.log("請求失敗" + code);
         })


五、封裝ajax的 get請求 (進階)

處理ie中緩存和編碼問題,
   ① 在ie瀏覽器下,如果發送一個相同url請求,它會通過本地緩存獲取數據,即只有一個結果,不能獲取到最新的數據
   ② 在ie中只能出現英文、數字、字母、下劃線、ASIIC碼,不能出現中文,韓文....它不會自動的進行編碼,所有需要手動的編碼
處理方案,對傳入的參數進一步的進行處理
   ① 給傳入的url添加一個隨機因子,也可以通過加入時間戳的方式,這樣不會出現相同的url請求
   ② 對傳入的參數可能出現中文的地方進行 encodeURL編碼

function json2Str(data) {
           //添加一個隨機因子, 處理方式也可以是添加時間戳
           data.r = Math.random();
           //定義數組
           var arr = [];
           //遍歷傳入的對象
           for (var key in data){
               //將json轉爲數組
               arr.push(key+'='+encodeURI(data[key]));
               console.log(arr);
           }
           //將數組轉爲固定格式的字符串
         return  arr.join('&'); //取出數組中的每一項,然後用&符號連接
       }



六、封裝ajax的 post請求的步驟


 //1 創建異步請求對象
    var xhr;
    if(XMLHttpRequest){
        xhr = new XMLHttpRequest();
    }
    else {
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }
    //2 設置url
    xhr.open('post','post.php',true);
    // 設置請求頭,請求頭的位置要放在open 和 send之間
    xhr.setRequestHeader("Content-type",'application/x-www-form-urlencoded');
    //3 發送請求
    xhr.send("name=zhang&age=12");
    //4 監聽響應 -->處理響應數據
    xhr.onreadystatechange = function () {
        if (xhr.readyState ==4){
            if (xhr.status >=200 && xhr.status <300 || xhr.status==304){
                console.log(xhr.responseText);
            }
            else {
                console.log(xhr.status);
            }
        }
    }

post請求的注意點:

   ①  不是拼接到url中,參數必須通過send方 法傳給服務器
   ②  設置請求頭,請求頭在open 和 send之間,這個位置是固定的  xhr.setRequestHeader("Content-type",'application/x-www-form-urlencoded');

七、封裝ajax的 ajax請求(包括post 和 get)

  //封裝的ajax請求方法
    function ajax(type,url,data,timeout,success,error) {
        var xhr;
        if(XMLHttpRequest){
            xhr = new XMLHttpRequest();
        }
        else {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }
        //處理參數
        var str =json2Str(data);
        //2 設置url
        if (type =='get'){
            xhr.open(type,url+'?'+str);
            xhr.send();
        }
        else {
            xhr.open('post',url,true);
            // 設置請求頭,請求頭的位置要放在open 和 send之間
            xhr.setRequestHeader("Content-type",'application/x-www-form-urlencoded');
            //3 發送請求
            xhr.send(str);
        }

        //4 監聽響應 –>處理響應數據
        xhr.onreadystatechange = function () {
            if (xhr.readyState ==4){
                clearTimeout(timer);
                if (xhr.status >=200 && xhr.status <300 || xhr.status==304){
                    success(xhr.responseText);
                }
                else {
                    error(xhr.status);
                }
            }
        }
        //超時處理
        if(timeout){
            var timer = setTimeout(function () {
                alert("請求超時");
                xhr.abort();//中斷請求
            },timeout)
        }
    }
    // 參入數據包裝
    function json2Str(data) {
        //添加一個隨機因子, 處理方式也可以是添加時間戳
        data.r = Math.random();
        //定義數組
        var arr = [];
        //遍歷傳入的對象
        for (var key in data){
            //將json轉爲數組
            arr.push(key+'='+encodeURI(data[key]));
            console.log(arr);
        }
        //將數組轉爲固定格式的字符串
        return  arr.join('&'); //取出數組中的每一項,然後用&符號連接
    }
    var data = {
        "name":'zhang',
        "age":21
    }
    //發送一個 ajax請求
   ajax('post','01-get.php',data,2000,function (res) {
       console.log(res);
   },function (e) {
       console.log(e);
   })


此處封裝兩大改動:
      ①  將 post 和 get請求封裝在一起,通過type 參數來指定類型
      ②  設置了請求的延時,當網絡不好的情況下,不然用戶一直等下去,採用的是定時器來設置的
    

問題:
通過這種方式,已經可以實現基本的ajax請求,但是它仍然存在很多缺陷:
    ①  使用這個方法的時候,我需要看封裝的方法,這樣才能知道要傳入幾個參數,而且參入參數的位置是什麼,這樣十分的不利於提高效率
    ②  容錯性差,有的參數是必須傳的參數,而有的參數可有可無,都沒有對他們進行容錯處理。

下面我們再一次封裝這個方法來解決存在的這兩個問題


八、封裝ajax的 ajax請求(終極)

 function json2str(json) {
        // 0.給json添加隨機因子
        json.t = Math.random();
        // 1.將json轉換爲數組
        var arr = [];
        for(var key in json){
            arr.push(key+"="+encodeURIComponent(json[key]));
        }
        // 2.將數組轉換爲字符串返回
        return arr.join("&");
    }
    function ajax(options) {
        // 1.判斷有沒有傳遞option
        options = options || {};
        // 2.判斷有沒有url
        if(!options.url){  //沒傳入url
            return ;
        }
        // 3.設置默認值
        options.type = options.type || "get";
        options.timeout = options.timeout || 0;
        options.data = options.data || {};

        // 4.將參數轉換爲固定格式字符串
        var str = json2str(options.data);

        // 1.創建異步對象
        if(window.XMLHttpRequest){
            var xhr = new XMLHttpRequest()
        }else{
            var xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }

        if(options.type == "get"){
            // 2.設置URL
            xhr.open(options.type, options.url+"?"+str, true);
            // 3.發送請求
            xhr.send();
        }else{
            // 2.設置URL
            xhr.open(options.type, options.url, true);

            // 設置請求頭
            xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

            // 3.發送請求
            xhr.send(str);
        }
        // 4.註冊事件
        xhr.onreadystatechange = function () {
            // 5.處理返回數據
            // 判斷請求狀態
            if(xhr.readyState == 4){
                clearTimeout(timer);
                // 判斷HTTP狀態
                if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
                    options.success(xhr.responseText);
                }else{
                    options.error(xhr.status);
                }
            }
        }
        // 6.超時處理
        if(options.timeout){
            var timer = setTimeout(function () {
                xhr.abort(); // 中斷請求
            }, options.timeout);
        }

    }
    //調用 ajax發送請求
    ajax({
        "type":"post",
        "url":'01-get.php',
        "data":{
           "name":"zhangsan",
            "age":21
        },
        "timeout":0,
        "success":function (res) {
            console.log(res);
        },
        "error":function (e) {
            console.log(e);
        }
    });

哈哈,花了幾個小時,希望對大家有幫助!



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章