偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Axios vs. fetch():哪個(gè)最適合 HTTP 請(qǐng)求?

開發(fā) 前端
在本文中,我將按照基本語法、向后兼容性、響應(yīng)超時(shí)、自動(dòng)JSON數(shù)據(jù)轉(zhuǎn)換、HTTP攔截器、下載進(jìn)度、同時(shí)請(qǐng)求這些方面來比較fetch()和Axios,看看它們?nèi)绾螆?zhí)行任務(wù)。

因?yàn)锳xios的易于使用,所以有些開發(fā)人員比起內(nèi)置的API,更喜歡Axios。

但許多人高估了這個(gè)庫。

fetch() API不但完全能夠重現(xiàn)Axios的關(guān)鍵功能,而且還有隨時(shí)可用于所有現(xiàn)代瀏覽器中的獨(dú)特優(yōu)勢。

在本文中,我將按照基本語法、向后兼容性、響應(yīng)超時(shí)、自動(dòng)JSON數(shù)據(jù)轉(zhuǎn)換、HTTP攔截器、下載進(jìn)度、同時(shí)請(qǐng)求這些方面來比較fetch()和Axios,看看它們?nèi)绾螆?zhí)行任務(wù)。

希望在本文結(jié)束時(shí),大家對(duì)這兩個(gè)API有了更深入的了解。

基本語法

在我們深入研究Axios更高級(jí)地功能之前,先與fetch()進(jìn)行基本語法的比較。

下面是Axios如何將帶有自定義請(qǐng)求頭的[POST]請(qǐng)求發(fā)送到指定URL的代碼:

// axios

const url = 'https://jsonplaceholder.typicode.com/posts'
const data = {
  a: 10,
  b: 20,
};
axios
  .post(url, data, {
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json;charset=UTF-8",
    },
  })
  .then(({data}) => {
    console.log(data);
});

與fetch()版本進(jìn)行比較:

// fetch()

const url = "https://jsonplaceholder.typicode.com/todos";
const options = {
  method: "POST",
  headers: {
    Accept: "application/json",
    "Content-Type": "application/json;charset=UTF-8",
  },
  body: JSON.stringify({
    a: 10,
    b: 20,
  }),
};
fetch(url, options)
  .then((response) => response.json())
  .then((data) => {
    console.log(data);
  });

注意:

  • 為發(fā)送數(shù)據(jù),fetch()使用body屬性將數(shù)據(jù)發(fā)送到服務(wù)端,而Axios使用data屬性
  • fetch()中的數(shù)據(jù)使用JSON.stringify方法轉(zhuǎn)換為字符串
  • Axios自動(dòng)轉(zhuǎn)換從服務(wù)器返回的數(shù)據(jù),但使用fetch()時(shí),你必須調(diào)用response.json方法將數(shù)據(jù)解析為JavaScript對(duì)象。
  • 使用Axios,服務(wù)器提供的數(shù)據(jù)響應(yīng)可以在數(shù)據(jù)對(duì)象中訪問,而對(duì)于fetch()方法,最終數(shù)據(jù)可以命名為任何變量

向后兼容性

Axios的主要賣點(diǎn)之一是其廣泛的瀏覽器支持。

即使是像IE11這樣的舊瀏覽器也可以毫無問題地運(yùn)行Axios。這是因?yàn)樗澈笫褂昧薠MLHttpRequest。

而fetch()僅支持Chrome 42+,F(xiàn)irefox 39+,Edge 14+和Safari 10.3+。

如果你使用Axios的唯一原因是向后兼容性,那么實(shí)際上并不需要HTTP庫。而且,你可以將fetch()與polyfill一起使用,在不支持fetch()的web瀏覽器上實(shí)現(xiàn)類似的功能。

要使用fetch() polyfill,可以通過npm命令進(jìn)行安裝,如下所示:

npm install whatwg-fetch --save

然后,提出如下請(qǐng)求:

import 'whatwg-fetch'
window.fetch(...)

謹(jǐn)記,在有些舊瀏覽器中,可能還需要promise polyfill。

響應(yīng)超時(shí)

在Axios中設(shè)置超時(shí)的簡單性,是一些開發(fā)人員比fetch()更喜歡Axios的原因之一。

在Axios中,你可以使用配置對(duì)象的timeout屬性來設(shè)置請(qǐng)求中止之前的毫秒數(shù)。

例如:

axios({
  method: 'post',
  url: '/login',
  timeout: 4000,    // 4 seconds timeout
  data: {
    firstName: 'David',
    lastName: 'Pollock'
  }
})
.then(response => {/* handle the response */})
.catch(error => console.error('timeout exceeded'))

Fetch()通過AbortController接口提供類似的功能。

不過,它的代碼不如Axios版本簡單:

const controller = new AbortController();
const options = {
  method: 'POST',
  signal: controller.signal,
  body: JSON.stringify({
    firstName: 'David',
    lastName: 'Pollock'
  })
};  
const promise = fetch('/login', options);
const timeoutId = setTimeout(() => controller.abort(), 4000);

promise
  .then(response => {/* handle the response */})
  .catch(error => console.error('timeout exceeded'));

代碼使用AbortController.abort()構(gòu)造函數(shù)創(chuàng)建AbortController對(duì)象,它允許我們稍后中止請(qǐng)求。

Signal是AbortController的只讀屬性,提供了一種與請(qǐng)求通信或中止請(qǐng)求的方法。

如果服務(wù)器在4秒內(nèi)沒有響應(yīng),則調(diào)用controller.abort(),終止操作。

自動(dòng)JSON數(shù)據(jù)轉(zhuǎn)換

如前所述,Axios在發(fā)送請(qǐng)求時(shí)會(huì)自動(dòng)字符串化數(shù)據(jù)(當(dāng)然你也可以覆蓋默認(rèn)行為并定義不同的轉(zhuǎn)換機(jī)制)。

但是,當(dāng)使用fetch()時(shí),你必須手動(dòng)執(zhí)行此操作。

比較:

// axios
axios.get('https://api.github.com/orgs/axios')
  .then(response => {
    console.log(response.data);
  }, error => {
    console.log(error);
  });
// fetch()
fetch('https://api.github.com/orgs/axios')
  .then(response => response.json())    // one extra step
  .then(data => {
    console.log(data) 
  })
  .catch(error => console.error(error));

自動(dòng)轉(zhuǎn)換數(shù)據(jù)是一個(gè)不錯(cuò)的功能,但同樣,這不是你不能用fetch()做的事情。

HTTP攔截器

Axios的主要功能之一是它能夠攔截HTTP請(qǐng)求。

當(dāng)你需要檢查或更改從應(yīng)用程序到服務(wù)器的HTTP請(qǐng)求時(shí),使用HTTP攔截器非常方便,從服務(wù)器到應(yīng)用程序亦是如此(例如,日志記錄、身份驗(yàn)證或重試失敗的HTTP請(qǐng)求)。

使用攔截器就不必為每個(gè)HTTP請(qǐng)求編寫單獨(dú)的代碼。

在你想要為處理請(qǐng)求和響應(yīng)設(shè)置全局策略時(shí),HTTP攔截器非常有用。

以下是在Axios中聲明請(qǐng)求攔截器的方法:

axios.interceptors.request.use(config => {
  // log a message before any HTTP request is sent
  console.log('Request was sent');

  return config;
});

// sent a GET request
axios.get('https://api.github.com/users/sideshowbarker')
  .then(response => {
    console.log(response.data);
  });

上面的代碼中,axios.interceptors.request.use()方法用于定義發(fā)送HTTP請(qǐng)求之前要運(yùn)行的代碼。而axios.interceptors.response.use()用于攔截來自服務(wù)器的響應(yīng)。

假設(shè)存在網(wǎng)絡(luò)錯(cuò)誤,那么通過響應(yīng)偵聽器,可以重試相同的請(qǐng)求。

默認(rèn)情況下,fetch()不提供攔截請(qǐng)求的方法,但它的解決方法也并不復(fù)雜。

那就是覆蓋全局fetch()方法并定義自己的攔截器,如下所示:

fetch = (originalFetch => {
  return (...arguments) => {
    const result = originalFetch.apply(this, arguments);
      return result.then(console.log('Request was sent'));
  };
})(fetch);

fetch('https://api.github.com/orgs/axios')
  .then(response => response.json())
  .then(data => {
    console.log(data) 
  });

下載進(jìn)度

進(jìn)度條在加載時(shí)非常有用,尤其是對(duì)于互聯(lián)網(wǎng)速度較慢的用戶。

以前,JavaScript程序員使用XMLHttpRequest.onprogress回調(diào)處理程序來實(shí)現(xiàn)進(jìn)度指示器。

Fetch API沒有onprogress處理程序。事實(shí)上,它通過響應(yīng)對(duì)象的body屬性來提供ReadableStream的實(shí)例。

以下示例表明如何使用ReadableStream在圖像下載期間為用戶提供即時(shí)反饋:

index.html
<!-- Wherever you html is -->
  <div id="progress" src="">progress</div>
  <img id="img">

script.js
'use strict'
const element = document.getElementById('progress');
fetch('https://fetch-progress.anthum.com/30kbps/images/sunrise-baseline.jpg')
  .then(response => {
    if (!response.ok) {
      throw Error(response.status+' '+response.statusText)
    }
    // ensure ReadableStream is supported
    if (!response.body) {
      throw Error('ReadableStream not yet supported in this browser.')
    }
    // store the size of the entity-body, in bytes
    const contentLength = response.headers.get('content-length');
    // ensure contentLength is available
    if (!contentLength) {
      throw Error('Content-Length response header unavailable');
    }
    // parse the integer into a base-10 number
    const total = parseInt(contentLength, 10);
    let loaded = 0;
    return new Response(
      // create and return a readable stream
      new ReadableStream({
        start(controller) {
          const reader = response.body.getReader();
          read();
          function read() {
            reader.read().then(({done, value}) => {
              if (done) {
                controller.close();
                return; 
              }
              loaded += value.byteLength;
              progress({loaded, total})
              controller.enqueue(value);
              read();
            }).catch(error => {
              console.error(error);
              controller.error(error)                  
            })
          }
        }
      })
    );
  })
  .then(response => 
    // construct a blob from the data
    response.blob()
  )
  .then(data => {
    // insert the downloaded image into the page
    document.getElementById('img').src = URL.createObjectURL(data);
  })
  .catch(error => {
    console.error(error);
  })
function progress({loaded, total}) {
  element.innerHTML = Math.round(loaded/total*100)+'%';
}

在Axios中實(shí)現(xiàn)進(jìn)度指示器更簡單,尤其是在使用Axios進(jìn)度條模塊時(shí)。

首先,包含以下樣式和腳本:

// the head of your HTML
    <link rel="stylesheet" type="text/css"
         />


// the body of your HTML
     <img id="img" />
    <button onclick="downloadFile()">Get Resource</button>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://cdn.rawgit.com/rikmms/progress-bar-4-axios/0a3acf92/dist/index.js"></script>

// add the following to customize the style

<style>
    #nprogress .bar {
        background: red !important;
    }
    #nprogress .peg {
        box-shadow: 0 0 10px red, 0 0 5px red !important;
    }
    #nprogress .spinner-icon {
        border-top-color: red !important;
        border-left-color: red !important;
    }
</style>

然后像這樣實(shí)現(xiàn)進(jìn)度條:

<script type="text/javascript">
        loadProgressBar();

        function downloadFile() {
          getRequest(
            "https://fetch-progress.anthum.com/30kbps/images/sunrise-baseline.jpg"
          );
        }

        function getRequest(url) {
          axios
            .get(url, { responseType: "blob" })
            .then(function (response) {
              const reader = new window.FileReader();
              reader.readAsDataURL(response.data);
              reader.onload = () => {
                document.getElementById("img").setAttribute("src", reader.result);
              };
            })
            .catch(function (error) {
              console.log(error);
            });
        }
      </script>

代碼使用FileReaderAPI異步讀取下載的圖像。

readAsDataURL方法以Base64編碼字符串的形式返回圖像的數(shù)據(jù),然后將其插入到img標(biāo)記的src屬性中以顯示圖像。

并發(fā)請(qǐng)求

為了同時(shí)發(fā)出多個(gè)請(qǐng)求,Axios提供axios.all()方法。

只需將請(qǐng)求數(shù)組傳遞給此方法,然后使用axios.spread()將響應(yīng)數(shù)組的屬性分配給單獨(dú)的變量:

axios.all([
  axios.get('https://api.github.com/users/iliakan'), 
  axios.get('https://api.github.com/users/taylorotwell')
])
.then(axios.spread((obj1, obj2) => {
  // Both requests are now complete
  console.log(obj1.data.login + ' has ' + obj1.data.public_repos + ' public repos on GitHub');
  console.log(obj2.data.login + ' has ' + obj2.data.public_repos + ' public repos on GitHub');
}));

也可以使用內(nèi)置的Promise.all()方法獲得相同的結(jié)果。

將所有fetch請(qǐng)求作為數(shù)組傳遞給Promise.all()。接著使用async函數(shù)處理響應(yīng),如下所示:

Promise.all([
  fetch('https://api.github.com/users/iliakan'),
  fetch('https://api.github.com/users/taylorotwell')
])
.then(async([res1, res2]) => {
  const a = await res1.json();
  const b = await res2.json();
  console.log(a.login + ' has ' + a.public_repos + ' public repos on GitHub');
  console.log(b.login + ' has ' + b.public_repos + ' public repos on GitHub');
})
.catch(error => {
  console.log(error);
});

結(jié)論

Axios在緊湊的軟件包中提供了一個(gè)易于使用的API,可滿足大多數(shù)HTTP通信需求。

而web瀏覽器提供的fetch()方法則能完全重現(xiàn)Axios庫的主要功能。

所以,是否加載客戶端HTTP API取決于你是否習(xí)慣使用內(nèi)置API。

編程快樂!

責(zé)任編輯:武曉燕 來源: 前端新世界
相關(guān)推薦

2017-01-15 11:14:47

超融合數(shù)據(jù)中心IT基礎(chǔ)設(shè)施

2017-11-29 14:48:01

Node.JSRails語言

2017-03-09 13:30:13

Linux游戲AMD

2023-07-10 09:18:39

Redis訂閱模型

2022-12-26 14:51:48

人工智能

2019-09-01 19:19:04

TensorFlowPyTorch深度學(xué)習(xí)

2020-03-17 15:55:12

Redis數(shù)據(jù)庫命令

2023-01-13 10:46:42

2012-05-16 11:53:39

虛擬化

2022-07-11 10:17:19

Swift編程語言項(xiàng)目

2016-01-26 09:58:28

云存儲(chǔ)云服務(wù)云安全

2017-06-27 15:08:05

大數(shù)據(jù)Apache SparKafka Strea

2009-01-19 16:54:50

數(shù)據(jù)挖掘CRM孤立點(diǎn)

2015-12-08 09:31:02

Linux系統(tǒng)操作系統(tǒng)

2023-10-08 13:42:00

Python Web框架

2018-09-07 06:30:50

物聯(lián)網(wǎng)平臺(tái)物聯(lián)網(wǎng)IOT

2021-02-14 10:09:04

數(shù)據(jù)目錄數(shù)據(jù)元數(shù)據(jù)

2018-07-16 08:50:31

固態(tài)硬盤內(nèi)存

2012-03-20 09:32:24

Linux服務(wù)器

2016-07-14 16:27:54

linux
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)