AJAX、$.ajax、axios、fetch、superagent

weixin_34224941發表於2019-04-11

原生AJAX

// 1. 建立連線
var xhr = null;
xhr = new XMLHttpRequest()
// 2. 連線伺服器
xhr.open('get', url, true)
// 3. 傳送請求
xhr.send(null);
// 4. 接受請求
xhr.onreadystatechange = function(){
    if(xhr.readyState == 4){
        if(xhr.status == 200){
            success(xhr.responseText);
        } else { // fail
            fail && fail(xhr.status);
        }
    }
}
複製程式碼
  • 優點:

    通過非同步模式,提升了使用者體驗. 優化了瀏覽器和伺服器之間的傳輸,減少不必要的資料往返,減少了頻寬佔用.

    Ajax在客戶端執行,承擔了一部分本來由伺服器承擔的工作,減少了大使用者量下的伺服器負載。

    Ajax可以實現動態不重新整理(區域性重新整理)

  • 缺點:

    安全問題 AJAX暴露了與伺服器互動的細節。

    對搜尋引擎的支援比較弱。

    不容易除錯。

$.ajax

jQuery對Ajax的封裝

$.ajax({
    dataType: 'json', // 設定返回值型別
    contentType: 'application/json', // 設定引數型別
    headers: {'Content-Type','application/json'},// 設定請求頭
    xhrFields: { withCredentials: true }, // 跨域攜帶cookie
    data: JSON.stringify({a: [{b:1, a:1}]}), // 傳遞引數
    error:function(xhr,status){  // 錯誤處理
       console.log(xhr,status);
    },
    success: function (data,status) {  // 獲取結果
       console.log(data,status);
    }
})
複製程式碼

$.ajax只接收一個引數,這個引數接收一系列配置

Axios

詳細可參考:www.jianshu.com/p/7a9fbcbb1…

axios基於Promise對原生的XHR進行了非常全面的封裝,使用方式也非常的優雅。另外,axios同樣提供了在node環境下的支援,可謂是網路請求的首選方案。支援所有現代瀏覽器,甚至包括 IE8+!

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
複製程式碼
  • 優點

    同時支援 Node.js 和瀏覽器

    支援 Promise API

    可以配置或取消請求

    可以設定響應超時

    支援防止跨站點請求偽造(XSRF)攻擊

    可以攔截未執行的請求或響應

    支援顯示上傳進度

    廣泛用於 React 和 Vue 專案

  • 缺點 用起來比較麻煩

Superagent

改良版 Ajax——與 Node.js HTTP 客戶端搭配使用

Superagent 是一個基於 Promise 的輕量級漸進式 AJAX API,非常適合傳送 HTTP 請求以及接收伺服器響應。

與 Axios 相同,它既適用於 Node,也適用於所有現代瀏覽器。

用 Superagent 發起 HTTP 請求就像在 request 物件上呼叫方法一樣簡單:

var superagent = require('superagent');

superagent.post(`${prefix}/payplatform/pay/pay`).withCredentials().send(params).set({'appType': 5, 'blackbox' : blackbox}).then(response => {
    let body = response.body;
    if (body.errno === 0) {
        return body.data;
    } else {
        return Promise.reject(body);
    }
});
複製程式碼
  • 優點

它有一個外掛生態,通過構建外掛可以實現更多功能

可配置

HTTP 請求傳送介面友好

可以為請求鏈式新增方法

適用於瀏覽器和 Node

支援顯示上傳和下載進度

支援分塊傳輸編碼

支援舊風格的回撥

繁榮的外掛生態,支援眾多常見功能

  • 缺點

其 API 不符合任何標準

Fetch

Fetch 是瀏覽器自帶的用於傳送請求的 API,旨在替代 XMLHttpRequest。

使用fetch,你不需要再額外載入一個外部資源。但它還沒有被瀏覽器完全支援,所以你仍然需要一個polyfill。

const options = {
    method: "POST", // 請求引數
    headers: { "Content-Type": "application/json"}, // 設定請求頭
    body: JSON.stringify({name:'123'}), // 請求引數
    credentials: "same-origin", // cookie設定
    mode: "cors", // 跨域
}
fetch('http://www.xxx.com',options).then(function(response) {
    return response.json();
}).then(function(myJson) {
    console.log(myJson); // 響應資料
}).catch(function(err){
    console.log(err); // 異常處理
})
複製程式碼
  • 優點

    靈活易用

    使用 Promise 避免回撥地獄

    支援所有現代瀏覽器

    遵循 request-response 方案

    語法簡單清晰

支援 React Native

  • 缺點

    不支援伺服器端使用

    缺乏開發庫的亮點功能,比如取消請求

    沒有內建預設值,如請求模式,請求頭,請求憑據。

最後 用promise封裝http請求

function getJSON (url) {
    return new Promise( (resolve, reject) => {
        var xhr = new XMLHttpRequest()
        xhr.open('GET', url, true)

        xhr.onreadystatechange = function () {
            if (this.readyState === 4) {
                if (this.status === 200) {
                    resolve(this.responseText, this)
                } else {
                    var resJson = { code: this.status, response: this.response }
                    reject(resJson, this)
                }
            }
        }

        xhr.send()
    })
}

function postJSON(url, data) {
    return new Promise( (resolve, reject) => {
        var xhr = new XMLHttpRequest()
        xhr.open("POST", url, true)
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

        xhr.onreadystatechange = function () {
            if (this.readyState === 4) {
                if (this.status === 200) {
                    resolve(JSON.parse(this.responseText), this)
                } else {
                    var resJson = { code: this.status, response: this.response }
                    reject(resJson, this)
                }
            }
        }

        xhr.send(JSON.stringify(data))
    })
}
複製程式碼
getJSON('/api/v1/xxx').then( value => { 
  // dosomething          
}).catch( error => {
  // dosomething         
})
複製程式碼

轉載於:https://juejin.im/post/5caed2f1f265da0389327fd8

相關文章