ajax、axios、fetch的區別

1. ajax

  • 使用步驟
  1. 創建 XmlHttpRequest 對象
  2. 調用 open 方法設置基本請求信息
  3. 設置發送的數據,發送請求
  4. 註冊監聽的回調函數
  5. 拿到返回值,對頁面進行更新
//1.創建Ajax對象
if (window.XMLHttpRequest) {
  var oAjax = new XMLHttpRequest();
} else {
  var oAjax = new ActiveXObject('Microsoft.XMLHTTP');
}

//2.連接服務器(打開和服務器的連接)
oAjax.open('GET', url, true);

//3.發送
oAjax.send();

//4.接收
oAjax.onreadystatechange = function() {
  if (oAjax.readyState == 4) {
    if (oAjax.status == 200) {
      //alert('成功了:'+oAjax.responseText);
      fnSucc(oAjax.responseText);
    } else {
      //alert('失敗了');
      if (fnFaild) {
        fnFaild();
      }
    }
  }
};

優缺點:

  • 本身是針對MVC的編程,不符合現在前端MVVM的浪潮
  • 基於原生的XHR開發,XHR本身的架構不夠清晰,已經有了fetch的替代方案

2, axios

Axios 是一個基於 promise 的 HTTP庫,可以再瀏覽器和Node.js中使用。

特性

  • 從瀏覽器中創建XMLHttpRequests
  • 從Node.js創建 http 請求
  • 支持Promise API
  • 攔截請求和響應
  • 轉換請求數據和相應數據
  • 取消請求
  • 自動轉換JSON數據
  • 客戶端支持防禦 XSRF
// 上面的請求也可以這樣做
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

多個 併發請求

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // 兩個請求現在都執行完成
  }));

優缺點:

  • 從 node.js 創建 http請求
  • 支持Promise API
  • 客戶端支持防止CSRF
  • 提供了一些併發請求的接口

3. fetch

Fetch API提供了一個JavaScript 接口,用於訪問和操縱HTTP 管道的部分,例如請求和響應。

它提供了一個全局的fetch()方法,該方法提供了一種簡單,合理的方式來跨網絡以不獲取資源。
fetch 是一種 HTTP 數據請求方式,是 XMLHTTPRequest 的一種替代方案。
fetch 不是 ajax 的進一步封裝,而是原生 js。
Fetch 函數就是原生 js。

fetch(url, option)
    .then(checkStatus) // 檢查錯誤碼
    .then(response => responseJson(response));
  • 當接收到一個代表錯誤的HTTP狀態碼時,從fetch()返回的Promise 不會被標記爲reject,即使該HTTP相應的狀態碼是404 或者 500。
    相反,它會將Promise狀態標記爲 resolve,僅當網絡故障時或請求被阻止時,纔會標記爲reject。
// 因此可以多加一個判斷,判斷狀態碼
export const checkStatus = response => {
  const { status } = response;
  if (status >= 200 && status < 300) {
    // 調用成功
    return response;
  }
  const errortext = codeMessage[status] || response.statusText;
  const error = new Error();
  error.name = status;
  error.response = response;
  error.errortext = errortext;
  throw error;
};
  • 默認情況加, fetch不會從服務端發送或接受任何cookie,如果站點依賴於用戶session,則會導致未經認證的請求。
/**
 * 處理response
 * @param response
 * @param type
 */
function responseJson(response, type) {
  if (response && isEmptyObject(response)) {
    // 初始化
    if (type && type === 'text') {
      return response.text();
    }
    if (type && type === 'blob') {
      return response.blob();
    }
    return response.json();
  }
  if (type && type === 'blob') {
    return response.blob();
  }
  errorCallback(response);
  return null;
}

response 這裏的response 只是一個HTTP響應,而不是真的JSON。爲了獲取JSON的內容我們需要使用對應的 .json() 、.text() 、 .blob()方法。

優缺點:

  • 符合關注分離,沒有將輸入、輸出和用事件來跟蹤的狀態混在一個對象裏。
  • 更加底層,提供了API豐富(request、response)
  • 脫離了XHR,是ES規範裏新的實現方式
    1. fetch 只對網絡請求報錯,對400/500 都當成功的請求,需要封裝去處理
    1. fetch 默認不會帶cookie,需要添加配置項
    1. fetch不支持abort,不支持超時控制,使用setTimeout 及 Promise.reject 的實現的超時控制並不能阻止請求過程繼續在後臺運行,造成了量的浪費
    1. fetch沒有辦法原生檢測請求的進度,而XHR可以
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章