Ajax Promise Axios

記錄一些前端知識

Ajax

Ajax : Asynchronous·+ XML縮寫,可以向服務器額外請求數據而不須卸載頁面。Ajax的核心爲XMLHttpRequest(XHR)html

建立一個xhr對象

由於IE5是第一款引入XHR對象的瀏覽器,在IE5中,XHR是經過MSXML庫中的ActiveX對象實現的,因此在IE瀏覽器中,XHR有三個不一樣的版本:MSXML2.XMLHttp、MSXML2.XMLHttp.3.0、MSXML2.XMLHttp.6.0<br/>
複製代碼
//對於IE7版本以前
function createXHR(){
    if(typeof agruments.callee.activeXString!='string'){
        var versions = ["MSXML2.XMLHttp","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp.6.0"],i,len;
        for(i=0;len = versions.length;i<len;i++){
            try{
                new ActiveXObject(versions[i])
                agruments.callee.activeXString = version[i];
            }catch(ex){
                
            }
        }
    }
    return new ActiveXObject(agruments.callee.activeXString);
}
//對於IE7+、Firefox、Opera、Chrome、Safari支持原生的XHR對象
var xhr = new XMLHttpRequest();
複製代碼

總結上面狀況前端

function createXHR(){
    if(typeof XMLHttpRequest!='undefined'){
        return new XMLHttpRequest();
    }else if(typeof ActiveXObject!='undefined'){
        if(typeof agruments.callee.activeXString!='string'){
            var versions = ["MSXML2.XMLHttp","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp.6.0"],i,len;
        for(i=0;len = versions.length;i<len;i++){
            try{
                new ActiveXObject(versions[i])
                agruments.callee.activeXString = version[i];
            }catch(ex){
                
            }
        }
    }
    return new ActiveXObject(agruments.callee.activeXString);
    }else{
        throw new Error("No XHR object available");
    }
}
var xhr = createXHR();
複製代碼

XHR的用法

(1)open():接受三個參數:請求類型,請求url,是否異步發送請求的布爾值。node

//調用open不會發送請求,只是啓動了一個請求以備發送
xhr.open("get",url,false);
複製代碼
  • GET:用於獲取資源
  • HEAD:與get方法相似,可是不返回message body 內容,返回HTTP頭信息
  • POST:向服務器提交數據
  • DELETE:刪除資源
  • PUT:與POST類似,可是PUT指定資源存放位置,可是POST由服務器本身決定
  • OPTIONS:用於獲取當前URL所支持的方法。若請求成功,則它會在HTTP頭中包含一個名爲「Allow」的頭,值是所支持的方法,如「GET, POST」

(2)send():接受一個參數,做爲請求主體發送的數據,若是不須要,則必須傳入null。調用send後請求會分派到服務器ios

(3)readyState:表示請求/響應過程的當前活動階段ajax

0 :未初始化,沒有調用open()方法
1 :啓動,調用open()方法,沒有調用send()
2 :發送,調用send,但沒有收到響應
3 :接收,收到部分響應數據
4 :完成,接收所有響應數據,並且能夠在客戶端使用
複製代碼

(4)onreadystatechange():由於readyState屬性值由一個變成另一個值,都會觸發onreadystatechange,能夠利用該事件檢驗readyState的值,必須在open()以前使用json

var xhr = createXHR();
xhr.onreadystatechange = function(){
    if(xhr.readyState ==4){
        if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
            console.log(xhr.reponseText)
        }else{
            console.log("Request was unsuccessful: "+xhr.status);
        }
    }
}
xhr.open("get",url,true);
xhr.send(null);
複製代碼

在瀏覽器收到服務器響應後,響應數據會自動填充到XHR對象的屬性中:axios

  • responseText :做爲響應主體被返回的文本
  • responseXML:若是響應的內容類型是「text/xml」或「application/xml」,這個屬性中將保存包含着響應數據的XML DOM文檔
  • status:響應的HTTP狀態
  • statusText:HTTP狀態的說明》

(4) Http頭部信息後端

  • accept:瀏覽器可以處理的內容類型
  • accept-charset:瀏覽器可以顯示的字符集
  • accept-encoding:瀏覽器可以處理的壓縮編碼
  • accept-language:瀏覽器當前設置的語言
  • connection:瀏覽器與服務器之間鏈接的類型
  • cookie:當前頁面設置的任何cookie
  • host:發送請求的頁面所在的域
  • referer:發送請求的頁面的url
  • user-agent:瀏覽器的用戶代理字符串

使用sendRequestHeader()方法能夠設置自定義的請求頭部信息,可是必須在open以後send以前使用數組

xhr.open("get",url,true);
xhr.sendRequestHeader("Content-Type","application/x-www-form-unlecoded");
xhr.send(null);
複製代碼

(5)超時設定 timeoutpromise

xhr.open("get",url,true);
xhr.sendRequestHeader("Content-Type","application/x-www-form-unlecoded");
xhr.timeout = 1000;
xhr.send(null);
複製代碼

優勢: 1.無刷新更新數據 2.異步與服務器通訊 3.先後端負載平衡

缺點:1.AJAX幹掉了Back和History功能,即對瀏覽器機制的破壞。 2.AJAX的安全問題。

$.ajax

該方法是 jQuery 底層 AJAX 實現。簡單易用的高層實現見 $.get, $.post 等。$.ajax() 返回其建立的 XMLHttpRequest 對象。

jQuery.ajax([settings]) 參數:

  • url: 發送請求的地址
  • async 默認值true,爲異步請求
  • beforeSend(XHR):Function 發送請求前可修改 XMLHttpRequest 對象的函數,如添加自定義 HTTP 頭。若是返回 false 能夠取消本次 ajax 請求
  • cache:默認值: true,dataType 爲 script 和 jsonp 時默認爲 false。設置爲 false 將不緩存此頁面。
  • contentType:默認值: "application/x-www-form-urlencoded"。發送信息至服務器時內容編碼類型。
  • context:這個對象用於設置 Ajax 相關回調函數的上下文。讓回調函數內 this 指向這個對象
$.ajax({ url: "test.html", context: document.body, success: function(){
        $(this).addClass("done");
      }})
複製代碼
  • data:發送到服務器的數據。將自動轉換爲請求字符串格式
  • error:請求失敗時調用此函數
  • success:請求成功後的回調函數
$.ajax({
             type: "GET",
             url: "test.json",
             data:data,
             dataType: "json",
             success: function(data){},
             error:function(err){}
         });
複製代碼

Promise

Promise解決回調地獄問題。

Promise的用法

let promise = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        let rand = Math.random();
        if(rand>0.3){
            resolve("大於0.3: "+rand)
        }else{
            reject("小於0.3: "+rand)
        }
    },1000)
})
複製代碼

利用構造函數模式建立一個對象,即promise._proto_ == Promise.prototype爲true。

Promise構造函數接收一個函數做爲參數,該函數接受兩個各位的函數resolve,reject爲參數。這兩個函數分別表明將當前Promise置爲fulfilled(解決)和rejected(拒絕)兩個狀態。

promise只是Promise的一個實例對象,在聲明的時候並不會當即執行,而每個Promise的實例對象都有一個then方法,這個方法就是用來處理以前的異步邏輯的結果。

promise.then(resolve=>{
console.log(resolve)
},reject=>{
    console.log(reject)
})
複製代碼

then方法也有兩個參數,第一個調用resolve函數,第二個調用reject函, 而且Promise的then()方法,then老是會返回一個Promise實例,由此能夠一直then().then()...

catch

這個方法實際上是then方法的一種特例.then(null, rejection)至關於咱們不使用then方法的第一個函數,只是用第二個函數;catch函數比較簡單,就是用來捕獲以前的then方法裏面的異常

var promise = new Promise((res,rej)=>{
    rej("error123456")
});
promise.then(()=>{
    consoel.log(123)
}).catch((err)=>{
    console.log(err)
})
//運行結果error123456
複製代碼

Promise.all

Promise.all能夠將多個Promise實例包裝成一個新的Promise實例。成功的時候返回的是一個結果數組,而失敗的時候則返回最早被reject失敗狀態的值

let p1 = new Promise((res,rej)=>{
    res("success 1");
})
let p2 = new Promise((res,rej)=>{
    res("success 2");
})
let p3 = new Promise((res,rej)=>{
    rej("error");
})

//["success 1", "success 2"]
Promise.all([p1,p2]).then(success=>{
    console.log(success)
}).catch(err=>{
     console.log(err)
})

//["success 1", undefined]
Promise.all([p1,p2.p3]).then(success=>{
    console.log(success)
}).catch(err=>{
     console.log(err)
})

//error
Promise.all([p1,p3,p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)      // 失敗了,打出 '失敗'
})
複製代碼

Promise.race

賽跑,哪一個Promise實例獲取結果結果快就返回哪一個,無論結果自己是成功狀態仍是失敗狀態

let p1 = new Promise((res,rej)=>{
    setTimeout(()=>{
        res("success 1");
    },500)
})
let p2 = new Promise((res,rej)=>{
    setTimeout(()=>{
        res("success 2");
    },1000)
})
//success 1
Promise.race([p1,p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)      // 失敗了,打出 '失敗'
})
複製代碼

一個簡單的promise的實現

juejin.im/post/5aa786…

ajax+promise

function request( url: String = "", method: String = "GET", data: Object = null, async: Boolean = true, headers: Object = { 'content-type': 'application/x-www-form-urlencoded' }) {
    let xhr = new XMLHttpRequest();
    method = method.toUpperCase();
    xhr.open(method, url, async);
    for (let header in headers) {
        xhr.setRequestHeader(header, headers[header])
    }
    xhr.send(method === "GET" ? null : JSON.stringify(data));
    return new Promise((resolve, reject) => {
        xhr.onreadystatechange = function () {
            if (this.readyState === 4) {
                if (this.status === 200) {
                    resolve(JSON.parse(this.responseText), this)
                } else {
                    let resJson = {code: this.status, response: this.response}
                    reject(resJson, this)
                }
            }
        };
    })
}
複製代碼

Axios

Axios 是一個基於 promise 的 HTTP 庫,能夠用在瀏覽器和 node.js 中。

使用方法

//get
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
  
  //post
  axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
複製代碼

axios + promise

import axios from "axios";

let cancel;
const CancelToken = axios.CancelToken;
//請求攔截器
axios.interceptors.request.use(config => {
//一些操做
    return config
}, error => {
    return Promise.reject(error)
})

//響應攔截器即異常處理
axios.interceptors.response.use(response => {
    return response
}, err => {
    //...一些操做
    return Promise.resolve(err.response)
})
axios.defaults.baseURL = 'XXX'
//設置默認請求頭
axios.defaults.headers = {
    'X-Requested-With': 'XMLHttpRequest'
}
axios.defaults.timeout = 10000
export default {
    //get請求
    get(url, param) {
        return new Promise((resolve, reject) => {
            axios({
                method: 'get',
                url,
                params: param,
                cancelToken: new CancelToken(c => {
                    cancel = c
                })
            }).then(res => {
                //能夠根據後端返回status作resolve仍是reject
                resolve(res)
            })
        })
    },
    //post請求
    post(url, param) {
        return new Promise((resolve, reject) => {
            axios({
                method: 'post',
                url,
                data: param,
                cancelToken: new CancelToken(c => {
                    cancel = c
                })
            }).then(res => {
                resolve(res)
            })
        })
    }
}

複製代碼
相關文章
相關標籤/搜索