ajax入門和封裝(五)

Ajax

  • 即Asynchronous Javascript And XML(異步JavaScript和XML),
  • 是一種js常用與異步通信的技術(shù)。也是指一種創(chuàng)建交互式網(wǎng)頁應(yīng)用的網(wǎng)頁開發(fā)技術(shù)。(也可以做同步通信,對講機)
    異步通信,依賴服務(wù)器,發(fā)請求出去,前端不受通信流程影響

同步異步

  1. 同步:指的是事件按先后順序依次進行,步驟之間存在依賴關(guān)系,不能顛倒,如,買菜,洗菜,切菜,燒菜
  2. 異步:典型場景:燒水,聽歌,玩手機,事件彼此 之間可以同時進行,事件并不被其他事件干擾或等待,事件之間不管誰先結(jié)束,燒水,看報紙,喝茶
  3. 通信步驟
  • 準備信紙————創(chuàng)建通信對象
var xhr = new XMLHttpRequest();
- 在早期IE版本中,使用ActiveXObject創(chuàng)建對象
  • 寫信————通信初始化
xhr.open("get","data.json",true);
  • 送信發(fā)信————發(fā)送
xhr.send();
  • 收到回信————監(jiān)聽
xhr.onreadystatechange =function(){
    if(readyState ==4){
        console.log(xhr.responseText);
    }
}
  • 讀信————取值

異步通信,依賴服務(wù)器,發(fā)請求出去,前端不受通信流程影響

ajax的詳細通信步驟,ajax通信,大量的通用方法

  1. 創(chuàng)建通信對象 使用XMLHttpRequest實例,通常變量都用xhr名字
var xhr = new XMLHttpRequest(); //new+構(gòu)造函數(shù)創(chuàng)建對象
  1. 初始化通信對象(發(fā)到哪里,怎么發(fā),發(fā)給誰),使用open函數(shù),open接收三個參數(shù),第一個是通信類型get/post,第二個參數(shù)url請求地址,第三個參數(shù),同步或異步,默認為true,表示異步。
xhr.open("get","data.json",true);
  1. 發(fā)送請求,使用send函數(shù),從這里開始,表現(xiàn)異步,等下面的監(jiān)聽完成后,send才結(jié)束,會返回2
xhr.send();
console.log(111);
        xhr.onreadystatechange = function(){ 
        //拿到數(shù)據(jù)
            if(xhr.readyState ==4){
            if(xhr.readyState ==4 || xhr.readyState ==3){
                console.log(xhr.responseText);
                        }
                    }
  • 3的狀態(tài)時,數(shù)據(jù)不大,一次接收到了,可能拿出來,可能數(shù)據(jù)未接收完整
  • 4的狀態(tài)一定能拿出數(shù)據(jù)
  • ajax請求數(shù)據(jù)通常放在xhr對象的responseText字段中
  • 使用onreadystatechange監(jiān)聽xhr對象readyState(注意大寫)屬性值0-4 ,標識整個通信過程,接收到變成3,接收完畢變成4

ajax核心通信步驟分為五部,我們可以通過跟蹤通信對象readyState屬性來判斷通信狀態(tài)和進度

  • 0到1是同步

readyState屬性 記錄當前通信進行到什么步驟,其狀態(tài)值為0-4

  • 0:當通信對象創(chuàng)建完畢未初始化
  • 1:當使用open初始化通信對象后狀態(tài)為1
  • 2:調(diào)用send發(fā)送請求后狀態(tài)為2
  • 3:開始接收返回數(shù)據(jù) 狀態(tài)為3
  • 4:表示數(shù)據(jù)接收完畢
  • 注意:ajax可以同步,只不過同步:必須在open步驟前面監(jiān)聽,不然監(jiān)聽不到了

get和post的區(qū)別

  • 報文:報文(message)是網(wǎng)絡(luò)中交換與傳輸?shù)臄?shù)據(jù)單位,及站點一次性要發(fā)送的數(shù)據(jù)塊。報文包含了將要發(fā)送的完整的數(shù)據(jù)信息,其長短很不一致,長度不限且可變。
  1. post在數(shù)據(jù)傳量上,較比get要大,可以發(fā)送M級別的數(shù)據(jù)。而get只能發(fā)送k界別
  2. post數(shù)據(jù)在報文內(nèi)部傳輸,較比get請求將參數(shù)拼接在url后面的方式,更安全
  3. get請求在處理請求時,速度會比post快,理論上快一倍

get方式傳參,參數(shù)在url后以?鍵=值&鍵=值...的方式傳遞eg:?name=violet&age=23&sex=男

  • 用按鈕ajax模擬get發(fā)送請求
<form action="" method= "get">
        姓名:<input type = "text" name= "name"/>
        年齡:<input type = "text" name= "age"/>
        性別:<input type = "text" name= "sex"/>
            <input type = "submit" value= "提交"/>
            <input type = "button" value= "ajax提交get"/> <!-- 用ajax傳參 -->
            <input type = "button" value= "ajax提交post"/>
    </form>
document.querySelector("input[type =button]").onclick = function(){
        //創(chuàng)建通信對象
        var url = "data.json?",
            inputs = document.querySelectorAll("input[type=text]");
            for(var n= 0;n < inputs.length;n++){
                url +=inputs[n].name+"="+inputs[n].value+"&";
            }
                //截取多余&
                url = url.substr(0,url.length-1); //截掉最后一個多余的&
        var xhr = new XMLHttpRequest();
        //初始化通信對象
        xhr.open("get",url,true);
        //發(fā)送請求
        xhr.send();
        //輸出返回值
        xhr.onreadystatechange = function(){
            console.log(xhr.responesText);
        }
    };

而post請求參數(shù)放在報文內(nèi)部傳遞,ajax請求中post類型傳參,將參數(shù)放在send函數(shù)實參形式傳遞

document.querySelectorAll("input[type =button]")[1].onclick = function(){
        //創(chuàng)建通信對象
        var url = "data.json",
            reqDate = {}, //上送空對象
            inputs = document.querySelectorAll("input[type=text]");

            for(var n= 0;n < inputs.length;n++){
                reqDate[inputs[n].name]=inputs[n].value;
                
            }
                
        var xhr = new XMLHttpRequest();
        //初始化通信對象
        xhr.open("post",url,true);
        //發(fā)送請求 post傳參 參數(shù)會被轉(zhuǎn)換為string上送給后臺
        xhr.send(JSON.stringify(reqDate));
        //輸出返回值
        xhr.onreadystatechange = function(){
            if(xhr.readyState ==4){
                var data = JSON.parse(xhr.responseText);
                console.log("我叫"+data.name+"我今年"+data.age);
            }
            
        };
    };

JSON 對象的使用,最主流的數(shù)據(jù)傳輸方式,就是JSON,多語言數(shù)據(jù)結(jié)構(gòu)

  • json格式字符串:通用的輕量級數(shù)據(jù)格式,解析比xml更快(輕量級)
  • 四種通用格式:{"鍵":值} || [值,值] ||
    {"鍵":[值,值]} || [{"鍵":值,"鍵":值}]
  • JSON.parse();將標準的JSON字符串轉(zhuǎn)換成對象,必須內(nèi)層加上雙引號,外層用單引號
console.log(JSON.parse('{"name":"tom","age":28}')); //輸出對象
  • JSON.stringify()將js對象轉(zhuǎn)換成JSON字符串
console.log(JSON.stringify({"name":"tom","age":28})); //輸出字符串{"name":"tom","age":28}
  • 一個對象轉(zhuǎn)化成字符串長度是15
  • .json文件中不能加注釋,否則報語法錯誤
  • encodeURIComponent(轉(zhuǎn)碼) 和 decodeURIComponent(變成中文)
  • utf-8,數(shù)字表示用幾位來表示中文,4位都不支持中文
  • utf-16,數(shù)字表示用16位表示一個字符

ajax封裝

  • ajax請求函數(shù)
  • @param:type 請求方式
  • @param:url 請求地址
  • @param:isAnsy 是否異步
  • @param:sendData 上送數(shù)據(jù) {key:value}
  • @param:callback 返回數(shù)據(jù),它的參數(shù)就是返回值
function postReq (type, url, isAnsy,sendData,callback){
            // 創(chuàng)建通訊對象
            var xhr = createXHr();
            // 根據(jù)請求方式處理上送數(shù)據(jù)
            if(type.toLowerCase() == "get"){
                // 將對象性數(shù)據(jù)轉(zhuǎn)換為queryString結(jié)構(gòu)
                url += "?";
                for(var n in sendData){
                    url += n +"=" + sendData[n] + "&";
                }
                // 截取末尾多余&
                url = url.substr(0,url.length-1);   
                // 設(shè)置sendDate為空null
                sendDate = null;
            }else{
                // 將js對象類型數(shù)據(jù)轉(zhuǎn)化為json格式的字符串
                sendData = JSON.stringify(sendData);
            }
            // 初始化通信對象
            xhr.open(type,url,isAnsy);
            // 發(fā)送請求
            xhr.send(sendData);

            // 監(jiān)聽請求返回狀態(tài)
            xhr.onreadystatechange = function(){
                    // xhr對象status屬性用于描述http通信狀態(tài)  statusText 是對status的描述信息
                    if(xhr.status == 200 || xhr.status == 304 || (xhr.status>200 && xhr.status<300)){
                        // console.log(xhr);
                        if(xhr.readyState == 4){
                        var resData = JSON.parse(xhr.responseText);
                        callback && callback(resData);
                    }               
                }
            }
        }
try{
            console.log(abc);   //可能出現(xiàn)異常的代碼
        }catch(e){
            console.log(e);   //異常事件處理   //異常出現(xiàn)時執(zhí)行的代碼
        }finally{
            console.log(33);  //無論是都會出現(xiàn)異常都要執(zhí)行的代碼
        }       
        console.log("aaaa");   //無論try中是否出現(xiàn)異常都不會影響后續(xù)代碼執(zhí)行

        // 創(chuàng)建一個兼容的xhr創(chuàng)建函數(shù)
        function createXHr(){
            絕大部分瀏覽器支持XMLHttpRequest
            if (typeof XMLHttpRequest == "function"){
                return new new XMLHttpRequest();
            }else{
                var strList = ["MSXML.XMLHttp.6.0","MSXML.XMLHttp.3.0","MSXML.XMLHttp", "Microsoft.XMLHTTP" //ie6];
                // 循環(huán)嘗試創(chuàng)建xhr對象
                for(var n = 0; n < strList.length; n++){
                    // 使用try catch 防止錯誤參數(shù)
                    try{
                        var xhr = new ActiveXObject(strList[n]);
                        // 返回xhr對象
                        return xhr;
                    }catch(e){
                        console.log(e);
                    }
                }
            }
        }
  • html加載自上向下,自外向內(nèi)優(yōu)先級比自上向下高,

  • 加載就是標簽節(jié)點,并不是

  • ajax的數(shù)據(jù)返回,如果要用數(shù)據(jù)有兩種方法:

  • 第一種:直接將所有的東西放到請求數(shù)據(jù)函數(shù)里面

  • 第二種:聲明全局變量,比如班級全局變量,數(shù)據(jù)全局變量,在請求函數(shù)里面賦值

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容