天天看點

Fetch還是Axios,哪個更适合HTTP請求?

Fetch還是Axios,哪個更适合HTTP請求?

作者 | Harsh Patel

前端開發最重要的部分之一是通過發出HTTP請求與後端進行通信,我們有幾種方法可以異步地在JavaScript中進行API調用。

幾年前,大多數應用程式都使用Ajax發送HTTP請求,Ajax代表異步JavaScript和XML。但是現在,開發人員通常會決定在 .fetch() API和Axios之間進行選擇。

在本文中,我想比較這兩種方法,并簡要介紹一下基本知識和文法。除此之外,我還将比較在兩種情況下以及在錯誤進行中将資料轉換為jsON格式的過程。我還将讨論HTTP攔截和下載下傳進度。

開始吧!

Fetch概述和文法

在建構Javascript項目時,我們可以使用window對象,并且它帶有許多可以在項目中使用的出色方法。這些功能之一是Fetch API,它提供了一種簡單的全局 .fetch() 方法,這是一種從API異步擷取資料的邏輯解決方案。

讓我們看一下 .fetch() 方法的文法。

fetch(url)
  .then((res) => 
    // handle response
  )
  .catch((error) => {
    // handle error
  })      

在上面的示例中,您可以看到簡單的擷取GET請求的文法。在 .fetch() 方法中,我們有一個強制性參數url,它傳回一個Promise,可以使用Response對象來解決。

.fetch() 方法的第二個參數是選項,它是可選的。如果我們不傳遞 options,請求總是GET,它從給定的URL下載下傳内容。

在選項參數裡面,我們可以傳遞方法或頭資訊,是以如果我們想使用POST方法或其他方法,我們必須使用這個可選的數組。

正如我之前提到的,Promise會傳回Response對象,正因為如此,我們需要使用另一個方法來擷取響應的主體。有幾種不同的方法可以使用,取決于我們需要的格式:

response.json()
response.text()
response.formData()
response.blob()
response.arrayBuffer()      

讓我們看一下帶有可選參數的代碼示例。

fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
});
  .then((response) => response.json())
  .catch((error) => console.log(error))      

在上面的代碼示例中,你可以看到簡單的POST請求,包括 method、header 和 body params。然後我使用 json() 方法将響應轉換為JSON格式。

現在,讓我們仔細看看axios。

Axios概述和文法

Axios是一個Javascript庫,用于從Node.js或XMLHttpRequests或浏覽器發出HTTP請求。作為一個現代的庫,它是基于Promise API的。

axios 有一些優勢,比如對XSRF的保護或取消請求。

為了能夠使用 axios 庫,我們必須将其安裝并導入到我們的項目中。可以使用CDN,npm或bower安裝 axios。現在,讓我們來看一個簡單的GET方法的文法。

axios.get(url)
  .then(response => console.log(response));
  .catch((error) => console.log(error));      

在上面的代碼中,你可以看到我使用 .get() 方法建立一個簡單的GET請求。如果你想在函數中使用POST方法,那麼隻需使用 .post() 方法代替,并将請求資料作為參數傳遞即可。

當我們建立配置對象時,我們可以定義一堆屬性,最常見的是:

baseUrl
params
headers
auth
responseType      

作為響應,axios 傳回一個promise,該promise将與響應對象或錯誤對象一起解析。在響應對象中,具有以下值:

data,這是實際的響應主體

status,調用的HTTP狀态,例如200或404

statusText,以文本消息形式傳回的HTTP狀态,例如 ok

headers,伺服器發回标頭

config,請求配置

request,XMLHttpRequest對象

現在,讓我們看一下帶有資料的POST方法的代碼示例。

axios.post({
  '/url', 
  { name: 'John', age: 22},
  { options }
})      

在上面的代碼中,你可以看到 post 方法,我們把config對象作為param,其中有URL、資料和附加選項。

我們還可以将config對象定義為變量,然後像下面的示例一樣将其傳遞給 axios。​

const config = {
  url: 'http://api.com',
  method: 'POST',
  header: {
    'Content-Type': 'application/json'
  },
  data: {
    name: 'John',
    age: 22
  }
}
axios(config);      

在這裡,你可以看到所有的參數,包括URL、資料或方法,都在config對象中,是以在一個地方定義所有的東西可能更容易。

JSON

如前所述,當我們在使用 .fetch() 方法的時候,需要對響應資料使用某種方法,當我們在發送帶有請求的body時,需要對資料進行字元串化。

在 axios 中,它是自動完成的,是以我們隻需在請求中傳遞資料或從響應中擷取資料。它是自動字元串化的,是以不需要其他操作。

讓我們看看如何從 fetch() 和 axios 擷取資料。​

// fetch
fetch('url')
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.log(error))
// axios
axios.get('url')
  .then((response) => console.log(response))
  .catch((error) => console.log(error))      

在上面的例子中,你可以看到,使用 axios 我們沒有額外的一行代碼,在 .fetch()的例子中,我們必須将資料轉換為JSON格式。在一個較大的項目中,如果你建立了大量的調用,那麼使用 axios 來避免重複代碼會更舒服。

錯誤處理

在這一點上,我們還需要給 axios 點贊,因為處理錯誤是非常容易的。

如果出現像404這樣的錯誤響應,promise就會被拒絕并傳回一個錯誤,是以我們需要捕獲一個錯誤,我們可以檢查它是什麼類型的錯誤,就是這樣。

讓我們看看代碼示例。

axios.get('url')
  .then((response) => console.log(response))
  .catch((error) => {
    if (error.response) {
      // When response status code is out of 2xx range 
      console.log(error.response.data)
      console.log(error.response.status)
      console.log(error.response.headers)
    } else if (error.request) {
      // When no response was recieved after request was made
      console.log(error.request)
    } else {
      // Error
      console.log(error.message)
    }
  })      

在上面的代碼中,當響應良好時,我傳回了資料,但是如果請求以任何方式失敗,我就能夠檢查 .catch() 部分中的錯誤類型并傳回正确的消息。

對于 .fetch() 方法,就比較複雜了。每次我們從 .fetch() 方法中得到響應時,我們需要檢查狀态是否成功,因為即使不是,我們也會得到響應。

在 .fetch() 的情況下,隻有當請求沒有完成時,promise才會被解決。讓我們看一下代碼示例。

fetch('url')
  .then((response) => {
    if (!response.ok) {
      throw Error(response.statusText);
    }
    return response.json()
  })
  .then((data) => console.log(data))
  .catch((error) => console.log(error))      

在這段代碼中,我已經在承諾對象中檢查了代碼的狀态,如果響應有狀态 ok,那麼我就可以處理并使用 .json() 方法,但如果沒有,我必須在 .then() 裡面傳回錯誤。

為了友善和正确的錯誤處理,對于你的項目來說,axios 絕對會是一個更好的解決方案,但如果你正在建構一個隻有一兩個請求的小項目,使用 .fetch() 是可以的,但你需要記住正确處理錯誤。

下載下傳進度

當我們需要下載下傳大量的資料時,一種跟蹤進度的方法會很有用,特别是當使用者的網絡速度很慢時。早期,為了實作進度名額,開發者使用了 XMLHttpRequest.onprogress 回調。在 .fetch() 和 axios 中,有不同的方法來實作。

為了在 .fetch() 中跟蹤下載下傳進度,我們可以使用其中一個 response.body 屬性,一個 ReadableStream 對象。它逐塊提供主體資料,并允許我們計算時間消耗了多少資料。

在axios中,實作一個進度訓示器也是可能的,而且更容易,因為存在一個現成的子產品,可以安裝和實作,它叫做Axios Progress Bar。

如果你有大量的大資料要下載下傳,你想跟蹤進度名額的進度,你可以用 axios 來管理,更容易更快,但 .fetch() 也提供了這種可能性,隻是它需要更多的代碼來開發同樣的結果。

HTTP攔截

當我們需要檢查或改變我們從應用程式到伺服器的HTTP請求時,或者以其他方式,例如,為了驗證,HTTP攔截可能是重要的。

在 axios 的情況下,HTTP攔截是這個庫的關鍵功能之一,這就是為什麼我們不需要建立額外的代碼來使用它。讓我們看一下代碼示例,看看我們能做到多麼容易。​

// 請求攔截
axios.interceptors.request.use((config) => {
  console.log('Request sent');
})
// 響應攔截
axios.interceptors.response.use((response) => {
  // do an operation on response
  return response
})
axios.get('url')
  .then((response) => console.log(response))
  .catch((error) => console.log(error))      

在代碼中,您可以看到請求攔截和響應攔截。在第一種情況下,我建立了一個 console.log,告知發送請求的情況,在響應攔截中,我們可以對響應做任何操作,然後傳回。

.fetch() 預設不提供HTTP攔截功能,我們可以覆寫 .fetch() 方法,定義發送請求過程中需要發生的事情,當然,這需要更多的代碼,可能比使用 axios 功能更複雜。

總結

在這篇文章中,我比較了用于建立HTTP請求的兩種方法,從簡單的概述開始,通過文法和一些重要的功能,如下載下傳進度或錯誤處理。

通過比較可以看出,對于有大量HTTP請求,需要良好的錯誤處理或HTTP攔截的應用,Axios是一個更好的解決方案。在小型項目的情況下,隻需要幾個簡單的API調用,Fetch也是一個不錯的解決方案。

在選擇項目的最佳解決方案時,還要注意一個因素,這是非常重要的。大多數浏覽器和Node.js環境都支援Axios,而現代浏覽器僅支援Fetch,并且某些版本可能會與舊版本一起釋出。

通過這些知識的了解,希望大家能夠選擇出最适合自己的方案,也希望大家覺得這個比較有幫助。

本文完~

Fetch還是Axios,哪個更适合HTTP請求?