前端開發最重要的部分之一是經過發出HTTP請求與後端進行通訊,咱們有幾種方法能夠異步地在Javascript中進行API調用。javascript
幾年前,大多數應用程序都使用Ajax發送HTTP請求,Ajax表明異步Javascript和XML。可是如今,開發人員一般會決定在 .fetch()
API和Axios之間進行選擇。前端
在本文中,我想比較這兩種方法,並簡要介紹一下基本知識和語法。除此以外,我還將比較在兩種狀況下以及在錯誤處理中將數據轉換爲JSON格式的過程。我還將討論HTTP攔截和下載進度。java
開始吧!ios
在構建Javascript項目時,咱們可使用window對象,而且它帶有許多能夠在項目中使用的出色方法。這些功能之一是Fetch API,它提供了一種簡單的全局 .fetch()
方法,這是一種從API異步獲取數據的邏輯解決方案。npm
讓咱們看一下 .fetch()
方法的語法。json
fetch(url) .then((res) => // handle response ) .catch((error) => { // handle error })
在上面的示例中,您能夠看到簡單的獲取GET請求的語法。在 .fetch()
方法中,咱們有一個強制性參數url,它返回一個Promise,可使用Response對象來解決。axios
.fetch()
方法的第二個參數是選項,它是可選的。若是咱們不傳遞 options
,請求老是GET,它從給定的URL下載內容。後端
在選項參數裏面,咱們能夠傳遞方法或頭信息,因此若是咱們想使用POST方法或其餘方法,咱們必須使用這個可選的數組。api
正如我以前提到的,Promise會返回Response對象,正由於如此,咱們須要使用另外一個方法來獲取響應的主體。有幾種不一樣的方法可使用,取決於咱們須要的格式:數組
讓咱們看一下帶有可選參數的代碼示例。
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是一個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()
方法代替,並將請求數據做爲參數傳遞便可。
當咱們建立配置對象時,咱們能夠定義一堆屬性,最多見的是:
做爲響應,axios
返回一個promise,該promise將與響應對象或錯誤對象一塊兒解析。在響應對象中,具備如下值:
ok
如今,讓咱們看一下帶有數據的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對象中,因此在一個地方定義全部的東西可能更容易。
如前所述,當咱們在使用 .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攔截多是重要的。
在 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,而且某些版本可能會與舊版本一塊兒發佈。
經過這些知識的瞭解,但願你們可以選擇出最適合本身的方案,也但願你們以爲這個比較有幫助。
感謝您的閱讀❤
來源:https://medium.com做者:Harsh Patel