AJAX發送get、post請求及部分優化的簡單理解

  • XMLHttpRequest對象是AJAX技術的核心
  • 簡單來講,AJAX發送並接受響應一共爲四步
let xhr = new XMLHttpRequest(); //建立XMLHttpRequest對象實例

xhr.open();                     //與服務端創建鏈接

xhr.send();                     //發送請求

xhr.onreadystatechange          //處理響應
複製代碼

注:IE中有三種不一樣的XHR對象,咱們這裏只談最經常使用的,適用於IE7及以上的前端

原生AJAX發送get請求

  • get請求很簡單,由於get請求沒有請求體,數據都是放置於URL後的,因此咱們只須要使用拼串方法便可 注:xhr.open方法中有三個參數(請求方法,拼串後的URL,是否異步傳輸),第三個參數由於默認是true(異步)因此能夠省略

前端頁面代碼ajax

let xhr = new XMLHttpRequest();

xhr.open('get','URL?value=string');//將拼串的URL放置此

xhr.send();

xhr.onreadystatechange = function(){
    if(xhr.readyState === 4 && xhr.status === 200){
        //接受響應的操做
    }
}
複製代碼

接收響應操做

readyState表明XHR對象所處於的狀態,他有5個值express

  • readyState = 0,還沒有調用open方法
  • readyState = 1,調用了open方法,但數據尚未發送
  • readyState = 2,數據已經發送,但沒有接收到響應
  • readyState = 3,接收到部分響應
  • readyState = 4,接收到所有響應,能夠查看

XHR對象接收到所有響應後,數據會填滿對象,此時須要調用onreadystatechange方法來監控XHR所處於的狀態,由於每當readyState數值發生變化,都會調用一次onreadystatechange方法後端

簡單優化

咱們通常在readyState = 4狀態時操做響應數據,而且咱們會監控服務端返回的狀態碼瀏覽器

當以2開頭時,服務器返回的響應即爲正確,除此以外,304的意思爲頁面正確且會重定向到瀏覽器已有的緩存文件,因此咱們能夠將接收操做處改成緩存

xhr.onreadystatechange = function(){
    if(xhr.readyState === 4 && ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304)){
        //接受響應的操做
    }
}
複製代碼

Node服務器代碼bash

app.get('/',(req,res)=>{
    console.log(req.query);//get請求使用query參數接收
    res.send('ok')
});
複製代碼

原生AJAX發送post請求

  • post與get方法不一樣的點在於,post方法發送的數據在請求體中,而且須要設置請求頭

前端頁面代碼服務器

let xhr = new XMLHttpRequest();

xhr.open('post','http://localhost:8088');//不須要拼串了

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

xhr.send('key=value');                  //發送數據(請求體)

xhr.onreadystatechange = function(){
    if(xhr.readyState === 4 && xhr.staus === 200){
        //接受響應的操做
    }
}
複製代碼

與前端頁面同樣,後端post也與get請求略微不一樣app

  • 首先,後端接受post請求的參數並非query而是body
  • 其次,Node並不能直接解析post請求,而是須要經過中間件

Node服務器代碼異步

app.use(express.urlencoded({extended:true}))//我使用的是express內置的中間件

app.post('/',(req,res)=>{
    let {key} = req.body;                   //咱們能夠直接使用解構賦值來獲取body中相應的值
    console.log({key});
    res.send('ok');
})
複製代碼

jQuery封裝AJAX

  • jQuery自己對AJAX進行了封裝,有兩種寫法,效果都同樣 前端頁面代碼
標準寫法:
$.ajax('請求的地址',{
    method:'',				//請求的方法
    data:{},				//請求的數據
    dataType:'',       //響應的數據類型
    success:(result)=>{},	//成功回調
    error:(err)=>{}			//失敗回調
})

簡寫:
$.get/post('請求地址',data,(data(響應的數據),success,xhr)=>{},dataType)
複製代碼

Promise封裝AJAX發送get請求

  • 咱們都知道Promise是前端進行異步操做的一種方法,並且經過上面的知識,咱們應該差很少了解了AJAX的基本用法,咱們如今就能夠根據jQuery的格式簡單封裝一下

前端頁面代碼

let sendAjax = function (method,url,data){
    return new Promise(()=>{
        let xhr = new XMLHttpRequest();
        
        //判斷是’get‘請求仍是’post‘請求
        if(method.toLowerCase() === 'get'){ 
            url += ('?' + data);      //get請求須要進行拼串操做

            xhr.open(method,url);

            xhr.send();
        }else   if(method.toLowerCase() === 'post'){
            xhr.open(method,url);

            xhr.setRequestHeader('content-Type','application/x-www-form-urlencoded')

            xhr.send(data);

        }

        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4 && ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304)){
                //接受響應的操做
                resolve();  //返回成功
            }else{
                reject();   //返回失敗
            }
        }
    })
}

function clickB(){
    sendAjax('post','http://localhost:8088','a=1')
}
複製代碼

優化

  • 咱們在上面已經進行了簡單的封裝,但咱們輸入數據通常都是以對象的方式進行存儲,那麼,咱們就須要將對象轉化爲URL的格式
  • 這裏咱們主要使用reduce累計的特性,來達到獲取對象中全部屬性值的目的
let keys = Object.keys(data);               //獲取全部的key值
if(data instanceof Object){                 //判斷是否爲對象,若是不是能夠將其轉化爲對象
   data =  keys.reduce((pre,now)=>{         //使用reduce方法累計附加對象中的key和value
       return pre += `${now}=${data[now]}&`;//使用模板字符串來簡化寫法
   },'')
}
複製代碼

最終版

let value = {
        name:'sys',
        age:18
    }
    let sendAjax = function (method,url,data){
        return new Promise(()=>{
            let xhr = new XMLHttpRequest();

            let keys = Object.keys(data);
            if(data instanceof Object){
                data =  keys.reduce((pre,now)=>{
                    return pre += `${now}=${data[now]}&`;
                },'')
            }

            if(method.toLowerCase() === 'get'){
                url += ('?'+ data);

                xhr.open(method,url);

                xhr.send();
            }else
            if(method.toLowerCase() === 'post'){
                xhr.open(method,url);

                xhr.setRequestHeader('content-Type','application/x-www-form-urlencoded')

                xhr.send(data);

            }

            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4 && xhr.staus === 200){
                    //接受響應的操做
                }
            }
        })
    }
    function clickB(){
        sendAjax('get','http://localhost:8088',value)
    }
複製代碼

借鑑:《JavaScript高級程序設計》 + 網上查找 + 本身的理解

若有錯誤,但願提出

但願你們都能早日拿到心儀的offer,加油,共勉

相關文章
相關標籤/搜索