<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Fetch還是Axios——哪個(gè)更適合HTTP請(qǐng)求?

          共 5393字,需瀏覽 11分鐘

           ·

          2020-11-29 01:07


          作者:杜尼卜
          來源:SegmentFault 思否社區(qū)



          前端開發(fā)最重要的部分之一是通過發(fā)出HTTP請(qǐng)求與后端進(jìn)行通信,我們有幾種方法可以異步地在Javascript中進(jìn)行API調(diào)用。


          幾年前,大多數(shù)應(yīng)用程序都使用Ajax發(fā)送HTTP請(qǐng)求,Ajax代表異步Javascript和XML。但是現(xiàn)在,開發(fā)人員通常會(huì)決定在 .fetch() API和Axios之間進(jìn)行選擇。


          在本文中,我想比較這兩種方法,并簡(jiǎn)要介紹一下基本知識(shí)和語法。除此之外,我還將比較在兩種情況下以及在錯(cuò)誤處理中將數(shù)據(jù)轉(zhuǎn)換為JSON格式的過程。我還將討論HTTP攔截和下載進(jìn)度。


          開始吧!




          Fetch概述和語法


          在構(gòu)建Javascript項(xiàng)目時(shí),我們可以使用window對(duì)象,并且它帶有許多可以在項(xiàng)目中使用的出色方法。這些功能之一是Fetch API,它提供了一種簡(jiǎn)單的全局 .fetch()?方法,這是一種從API異步獲取數(shù)據(jù)的邏輯解決方案。


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


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


          在上面的示例中,您可以看到簡(jiǎn)單的獲取GET請(qǐng)求的語法。在 .fetch()?方法中,我們有一個(gè)強(qiáng)制性參數(shù)url,它返回一個(gè)Promise,可以使用Response對(duì)象來解決。


          .fetch()?方法的第二個(gè)參數(shù)是選項(xiàng),它是可選的。如果我們不傳遞 options,請(qǐng)求總是GET,它從給定的URL下載內(nèi)容。


          在選項(xiàng)參數(shù)里面,我們可以傳遞方法或頭信息,所以如果我們想使用POST方法或其他方法,我們必須使用這個(gè)可選的數(shù)組。


          正如我之前提到的,Promise會(huì)返回Response對(duì)象,正因?yàn)槿绱耍覀冃枰褂昧硪粋€(gè)方法來獲取響應(yīng)的主體。有幾種不同的方法可以使用,取決于我們需要的格式:


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

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

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

          在上面的代碼示例中,你可以看到簡(jiǎn)單的POST請(qǐng)求,包括 method、header 和 body params。然后我使用 json()?方法將響應(yīng)轉(zhuǎn)換為JSON格式。

          現(xiàn)在,讓我們仔細(xì)看看axios。



          Axios概述和語法


          Axios是一個(gè)Javascript庫,用于從Node.js或XMLHttpRequests或?yàn)g覽器發(fā)出HTTP請(qǐng)求。作為一個(gè)現(xiàn)代的庫,它是基于Promise API的。

          axios 有一些優(yōu)勢(shì),比如對(duì)XSRF的保護(hù)或取消請(qǐng)求。

          為了能夠使用 axios 庫,我們必須將其安裝并導(dǎo)入到我們的項(xiàng)目中。可以使用CDN,npm或bower安裝 axios。現(xiàn)在,讓我們來看一個(gè)簡(jiǎn)單的GET方法的語法。

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

          在上面的代碼中,你可以看到我使用 .get()?方法創(chuàng)建一個(gè)簡(jiǎn)單的GET請(qǐng)求。如果你想在函數(shù)中使用POST方法,那么只需使用 .post()?方法代替,并將請(qǐng)求數(shù)據(jù)作為參數(shù)傳遞即可。

          當(dāng)我們創(chuàng)建配置對(duì)象時(shí),我們可以定義一堆屬性,最常見的是:

          • baseUrl
          • params
          • headers
          • auth
          • responseType

          作為響應(yīng),axios 返回一個(gè)promise,該promise將與響應(yīng)對(duì)象或錯(cuò)誤對(duì)象一起解析。在響應(yīng)對(duì)象中,具有以下值:

          • data,這是實(shí)際的響應(yīng)主體
          • status,調(diào)用的HTTP狀態(tài),例如200或404
          • statusText,以文本消息形式返回的HTTP狀態(tài),例如?ok
          • headers,服務(wù)器發(fā)回標(biāo)頭
          • config,請(qǐng)求配置
          • request,XMLHttpRequest對(duì)象

          現(xiàn)在,讓我們看一下帶有數(shù)據(jù)的POST方法的代碼示例。

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

          在上面的代碼中,你可以看到 post 方法,我們把config對(duì)象作為param,其中有URL、數(shù)據(jù)和附加選項(xiàng)。

          我們還可以將config對(duì)象定義為變量,然后像下面的示例一樣將其傳遞給 axios。

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

          在這里,你可以看到所有的參數(shù),包括URL、數(shù)據(jù)或方法,都在config對(duì)象中,所以在一個(gè)地方定義所有的東西可能更容易。



          JSON

          如前所述,當(dāng)我們?cè)谑褂?.fetch()?方法的時(shí)候,需要對(duì)響應(yīng)數(shù)據(jù)使用某種方法,當(dāng)我們?cè)诎l(fā)送帶有請(qǐng)求的body時(shí),需要對(duì)數(shù)據(jù)進(jìn)行字符串化。

          在 axios 中,它是自動(dòng)完成的,所以我們只需在請(qǐng)求中傳遞數(shù)據(jù)或從響應(yīng)中獲取數(shù)據(jù)。它是自動(dòng)字符串化的,所以不需要其他操作。

          讓我們看看如何從 fetch()?和 axios 獲取數(shù)據(jù)。

          //?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()的例子中,我們必須將數(shù)據(jù)轉(zhuǎn)換為JSON格式。在一個(gè)較大的項(xiàng)目中,如果你創(chuàng)建了大量的調(diào)用,那么使用 axios 來避免重復(fù)代碼會(huì)更舒服。



          錯(cuò)誤處理


          在這一點(diǎn)上,我們還需要給 axios 點(diǎn)贊,因?yàn)樘幚礤e(cuò)誤是非常容易的。如果出現(xiàn)像404這樣的錯(cuò)誤響應(yīng),promise就會(huì)被拒絕并返回一個(gè)錯(cuò)誤,所以我們需要捕獲一個(gè)錯(cuò)誤,我們可以檢查它是什么類型的錯(cuò)誤,就是這樣。讓我們看看代碼示例。

          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)
          ????}
          ??})

          在上面的代碼中,當(dāng)響應(yīng)良好時(shí),我返回了數(shù)據(jù),但是如果請(qǐng)求以任何方式失敗,我就能夠檢查 .catch()?部分中的錯(cuò)誤類型并返回正確的消息。

          對(duì)于 .fetch()?方法,就比較復(fù)雜了。每次我們從 .fetch()?方法中得到響應(yīng)時(shí),我們需要檢查狀態(tài)是否成功,因?yàn)榧词共皇牵覀円矔?huì)得到響應(yīng)。在 .fetch()?的情況下,只有當(dāng)請(qǐng)求沒有完成時(shí),promise才會(huì)被解決。讓我們看一下代碼示例。

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

          在這段代碼中,我已經(jīng)在承諾對(duì)象中檢查了代碼的狀態(tài),如果響應(yīng)有狀態(tài) ok,那么我就可以處理并使用 .json()?方法,但如果沒有,我必須在 .then()?里面返回錯(cuò)誤。

          為了方便和正確的錯(cuò)誤處理,對(duì)于你的項(xiàng)目來說,axios 絕對(duì)會(huì)是一個(gè)更好的解決方案,但如果你正在構(gòu)建一個(gè)只有一兩個(gè)請(qǐng)求的小項(xiàng)目,使用 .fetch()?是可以的,但你需要記住正確處理錯(cuò)誤。



          下載進(jìn)度


          當(dāng)我們需要下載大量的數(shù)據(jù)時(shí),一種跟蹤進(jìn)度的方法會(huì)很有用,特別是當(dāng)用戶的網(wǎng)絡(luò)速度很慢時(shí)。早期,為了實(shí)現(xiàn)進(jìn)度指標(biāo),開發(fā)者使用了 XMLHttpRequest.onprogress 回調(diào)。在 .fetch()?和 axios 中,有不同的方法來實(shí)現(xiàn)。

          為了在 .fetch()?中跟蹤下載進(jìn)度,我們可以使用其中一個(gè) response.body 屬性,一個(gè) ReadableStream 對(duì)象。它逐塊提供主體數(shù)據(jù),并允許我們計(jì)算時(shí)間消耗了多少數(shù)據(jù)。

          在axios中,實(shí)現(xiàn)一個(gè)進(jìn)度指示器也是可能的,而且更容易,因?yàn)榇嬖谝粋€(gè)現(xiàn)成的模塊,可以安裝和實(shí)現(xiàn),它叫做Axios Progress Bar。

          如果你有大量的大數(shù)據(jù)要下載,你想跟蹤進(jìn)度指標(biāo)的進(jìn)度,你可以用 axios 來管理,更容易更快,但 .fetch()?也提供了這種可能性,只是它需要更多的代碼來開發(fā)同樣的結(jié)果。



          HTTP攔截


          當(dāng)我們需要檢查或改變我們從應(yīng)用程序到服務(wù)器的HTTP請(qǐng)求時(shí),或者以其他方式,例如,為了驗(yàn)證,HTTP攔截可能是重要的。

          在 axios 的情況下,HTTP攔截是這個(gè)庫的關(guān)鍵功能之一,這就是為什么我們不需要?jiǎng)?chuàng)建額外的代碼來使用它。讓我們看一下代碼示例,看看我們能做到多么容易。

          //?請(qǐng)求攔截
          axios.interceptors.request.use((config)?=>?{
          ??console.log('Request?sent');
          })
          //?響應(yīng)攔截
          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))

          在代碼中,您可以看到請(qǐng)求攔截和響應(yīng)攔截。在第一種情況下,我創(chuàng)建了一個(gè) console.log,告知發(fā)送請(qǐng)求的情況,在響應(yīng)攔截中,我們可以對(duì)響應(yīng)做任何操作,然后返回。

          .fetch()?默認(rèn)不提供HTTP攔截功能,我們可以覆蓋 .fetch()?方法,定義發(fā)送請(qǐng)求過程中需要發(fā)生的事情,當(dāng)然,這需要更多的代碼,可能比使用 axios 功能更復(fù)雜。



          總結(jié)


          在這篇文章中,我比較了用于創(chuàng)建HTTP請(qǐng)求的兩種方法,從簡(jiǎn)單的概述開始,通過語法和一些重要的功能,如下載進(jìn)度或錯(cuò)誤處理。

          通過比較可以看出,對(duì)于有大量HTTP請(qǐng)求,需要良好的錯(cuò)誤處理或HTTP攔截的應(yīng)用,Axios是一個(gè)更好的解決方案。在小型項(xiàng)目的情況下,只需要幾個(gè)簡(jiǎn)單的API調(diào)用,F(xiàn)etch也是一個(gè)不錯(cuò)的解決方案。

          在選擇項(xiàng)目的最佳解決方案時(shí),還要注意一個(gè)因素,這是非常重要的。大多數(shù)瀏覽器和Node.js環(huán)境都支持Axios,而現(xiàn)代瀏覽器僅支持Fetch,并且某些版本可能會(huì)與舊版本一起發(fā)布。

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

          感謝您的閱讀



          點(diǎn)擊左下角閱讀原文,到?SegmentFault 思否社區(qū)?和文章作者展開更多互動(dòng)和交流。

          -?END -

          瀏覽 46
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色免费日本欧美 | 人人艹人人摸人人 | 久热精品在线 | 狂野欧美做受XXXX高潮 | 免费做爱视频动漫 |