Ajax設置請求和接收響應、本身封裝簡易jQuery.Ajax、回調函數

Ajax設置請求和接收響應、本身封裝簡易jQuery.Ajax

這篇文章是承接前幾篇博客的,是前幾篇繼續學習
包括Ajax學習與理解簡化版本身實現jQuery
這篇文章只算是個人我的學習筆記,內容沒有精心排版,一些錯誤請見諒.javascript

全部代碼都在這裏,從歷史commit能夠看到全部代碼,擺闊一個簡易的node.js服務器
全部代碼在歷史commit裏(AjaxStudy---github)html

1JS設置任意請求

一個http請求分爲四個部分
請求行,請求頭,回車,請求體java

PBhECR.png

設置請求的四個部分(第三部分爲回車):node

  • 第一部分 request.open('get', '/xxx')
  • 第二部分 request.setRequestHeader('content-type','x-www-form-urlencoded')
  • 第四部分 request.send('a=1&b=2')

request.setRequestHeader()方法須要注意的是此方法必須在 open() 方法和 send() 之間調用。
XMLHttpRequest.setRequestHeader()jquery

另外須要注意的是,若是設置西請求方法爲get 而且設置了請求體(第四部分),在谷歌瀏覽器中看不到請求體,不報錯可是不顯示
示例代碼:git

myButton.addEventListener("click",(e)=>{
    let request = new XMLHttpRequest();
    request.open('POST','/xxx')//配置request
    //設置第二部分
    request.setRequestHeader("mataotao","123123xxx")
    request.setRequestHeader('content-type','x-www-form-urlencoded')
    request.send("a=1&b=2");//發送請求

    request.onreadystatechange = ()=>{
        if(request.readyState ===4){
            console.log("請求和響應都完畢了");
            if ( request.status>=200&&request.status<=400){
                console.log('說明請求成功');
                let string = request.responseText;
                //把符合json語法的字符串轉化爲js對應的值
                let object2 = window.JSON.parse(string);
                console.log(object2)
            }else if(request.status>=400){
                console.log("響應失敗");
            }
        } 
    }
})

查看請求
PBhJ2t.pnggithub

2JS獲取任意響應

響應的四個部分
PBTl9J.png
獲取四個部分的響應ajax

  • 第一部分 request.status / request.statusText
  • 第二部分 request.getResponseHeader() / request.getAllResponseHeaders()
  • 第四部分 request.responseText
myButton.addEventListener("click",(e)=>{
    let request = new XMLHttpRequest();
    request.open('POST','/xxx')//配置request
    //設置第二部分
    request.setRequestHeader("mataotao","123123xxx")
    request.setRequestHeader('content-type','x-www-form-urlencoded')
    request.send("a=1&b=2");//發送請求

    request.onreadystatechange = ()=>{
        if(request.readyState ===4){
            console.log("請求和響應都完畢了");
            if ( request.status>=200&&request.status<=400){
                console.log('說明請求成功');

                //*核心代碼 */
                //第一部分:
                console.log("獲取響應第一部分:")
                console.log(request.status)//200
                console.log(request.statusText)//ok

                //第二部分:
                console.log("獲取響應第二部分:")
                console.log(request.getResponseHeader('Content-Type'))
                console.log(request.getAllResponseHeaders())

                //第四部分:
                console.log("獲取響應第四部分:")
                console.log(request.responseText)
                 //*核心代碼 */


                let string = request.responseText;
                //把符合json語法的字符串轉化爲js對應的值
                let object2 = window.JSON.parse(string);
                // console.log(object2)

            }else if(request.status>=400){
                console.log("響應失敗");
            }
        } 
    }
})

PBTEXq.png

3 客戶端/服務器模型

客戶端使用js設置請求的四個部分,
服務器用nodejs也能夠設置響應的四個部分
PDKjB9.pngjson

PDMDu4.png

爲何要三次握手?

三次握手:
A:我能連你了嗎?
B: 能夠連我,你連吧
A:那我連你了
開始發送數據segmentfault

緣由:由於要保證A/B 均可以收發信息 ,數據才能在AB之間傳輸

1.
A:我能連你了嗎?
B: 能夠
說明A能夠發信息,B能夠接受信息

2.
B: 能夠連我,你連吧
A:那我連你了
說明B能夠發送信息,A能夠接受信息

3 本身封裝jQuery.Ajax(簡單原理)

全部代碼在歷史commit裏(AjaxStudy---github)

3.1 方法一

window.jQuery = ()=>{//僞裝有一個簡易的jQuery,具體封裝
    let object1 = {};
    boject1.addClass = function(){};
    boject1.show = function(){};
    return object1;
}

window.jQuery.ajax = (method,path,body,successFn,failFn)=>{
    let request = new XMLHttpRequest();
    request.open(method,path)
    request.send(body);
    request.onreadystatechange = ()=>{
        if(request.readyState ===4){
            if ( request.status>=200&&request.status<=400){
                successFn.call(undefined,request.responseText)//執行成功函數
            }else if(request.status>=400){
                failFn.call(undefined,request)//執行失敗函數
            }
        }
    }
}

window.$ = window.jQuery;
myButton.addEventListener("click",(e)=>{
    //使用ajax
    $.ajax("post",
           "/xxx",
           "username=mtt&password=1",
           function(result){
                console.log('成功了,返回的響應體爲:')
                console.log(result);//打印request.responseText
           },
           function(result){
                console.log(result);
                console.log(result.status);//打印失敗的狀態碼
                console.log(result.responseText);//打印失敗時返回的響應體
                
           }
)
})

結果:
成功時:
PDgT5n.png

PDgb80.png

失敗時:(假如請求一個不存在的路徑,響應狀態碼是404,可是也有響應體responseText)

例如,訪問一個不存在的路徑/frank:

myButton.addEventListener("click",(e)=>{
    //使用ajax
    $.ajax("post",
           "/frank",
           "username=mtt&password=1",
           function(result){
                console.log('成功了,返回的響應體爲:')
                console.log(result);//打印request.responseText
           },
           function(result){
                console.log(result);
                console.log(result.status);//打印失敗的狀態碼
                console.log(result.responseText);//打印失敗時返回的響應體
                
           }
)
})

返回狀態碼404,並且有設置的返回體
PDWinO.png
由於個人服務器端的代碼爲:

else {
    response.statusCode = 404
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
    response.write(`{
      "error":"404error"
    }`)
    response.end()
  }

這種方法的缺點:這個函數必須按照規定的順序傳參,第二,若是沒有參數就會出現相似於$.ajax("post",null,successFn,null)的狀況,必須傳有結構的參數(對象)

3.2什麼是回調

在上面的代碼中,在ajax函數中傳了一個successFN,failFn函數做爲參數,可是執行的時候是在別的地方執行的(在request.onreadystatechange裏)

if(request.readyState ===4){
            if ( request.status>=200&&request.status<=400){
                successFn.call(undefined,request.responseText)//執行成功函數
            }else if(request.status>=400){
                failFn.call(undefined,request)//執行失敗函數

這兩個函數就是回調函數

回調(callback):
回來執行的意思,本身不call.
把這個函數給別人,本身不執行,讓別人執行,就是callback

回調:使用方代碼不執行,只傳一個函數,回來再執行

回調就是傳一個函數,本身不執行,傳到別的地方讓他在那裏執行的函數!只要知足這個條件就叫回調而已.他是一個函數,只不過在別的地方執行了

因此看上去沒有執行,實際上success了就執行傳進去的這個函數

3.3封裝方法二:傳有結構的參數(對象)

let myButton = document.getElementById('myButton');

window.jQuery = ()=>{//僞裝有一個簡易的jQuery
    let object1 = {};
    boject1.addClass = function(){};
    boject1.show = function(){};
    return object1;
}

window.jQuery.ajax = (options)=>{
    //獲取傳進來的對象的value
    let method = options.method;
    let path = options.path;
    let body = options.body;
    let successFn = options.successFn;
    let failFn = options.failFn;
    let headers = options.headers;

    let request = new XMLHttpRequest();
    request.open(method,path);//配置

    for (const key in headers) {//遍歷header,設置響應頭
        let value = headers[key];
        request.setRequestHeader(key,value);
    }
    request.send(body);//發送,並配置響應體

    request.onreadystatechange = ()=>{
        if(request.readyState ===4){
            if ( request.status>=200&&request.status<=400){
                successFn.call(undefined,request.responseText);//執行成功函數
            }else if(request.status>=400){
                failFn.call(undefined,request);//執行失敗函數
            }
        }
    }
}

window.$ = window.jQuery;
myButton.addEventListener("click",(e)=>{
    //使用ajax
    $.ajax({
        method:"post",
        path:"/xxx",
        body:"username=mtt&password=1",
        headers:{
            "content-type":'application/x-www-form-urlencoded',
            "mataotao":18
        },
        successFn:function(result){//成功函數的回調
            console.log('成功了,返回的響應體爲:');
            console.log(result);//打印request.responseTex
        },
        failFn:function(){
            console.log(result);
            console.log(result.status);//打印失敗的狀態碼
            console.log(result.responseText);//打印失敗時返回的響應體
        }
    }
)
})

結果:

PD4lDK.png

PD4Qu6.png

4真正的jQuery.ajax()API如何使用

jQuery.ajax()API
例子

$.ajax({
  type: "GET",
  url: "/test",
  dataType: "script",
  data:{}
  success:function(){},
});

dataType就是setRequestHeader("content-type","application/javascript")

data就是請求的第四部分

5函數傳不一樣的參數

例如文檔裏的
jQuery.ajax( url [, settings ] )

jQuery.ajax( [settings ] )
jQuery.ajax第一個參數既能夠是url字符串你也能夠是對象
如何實現這種封裝?
只要在最開始判斷參數長度便可

let url;
    if(arguments.length===1){//參數長度爲1
        url = options.url;
    }else if(arguments.length===2){//參數長度爲2
        url = arguments[0];
        options = arguments[1];
    }

其他代碼不變
PDI1te.png

6 一點點ES6語法:解構賦值

解構賦值MDN
PrVD58.png
或者直接

clipboard.png

相關文章
相關標籤/搜索