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

前端請求大比拼:Fetch、Axios、Ajax、XHR

開發(fā) 前端
XMLHttpRequest 是一個內(nèi)置的 JavaScript 對象,XMLHttpRequest(XHR)對象用于與服務器交互。通過 XMLHttpRequest 可以在不刷新頁面的情況下請求特定 URL,獲取數(shù)據(jù)。這允許網(wǎng)頁在不影響用戶操作的情況下,更新頁面的局部內(nèi)容。

當涉及前端網(wǎng)絡(luò)請求時,有許多工具/技術(shù)可供選擇,包括 Fetch、Axios、Ajax 和 XHR 等。這些技術(shù)在發(fā)送和處理HTTP請求方面提供了不同的功能和方法。本文將深入探討這些技術(shù)的特點、優(yōu)勢和用法,幫你更好地理解并選擇最適合項目需求的技術(shù)。

1、基本概念

Fetch、Axios、Ajax 和XHR都是前端用于發(fā)送HTTP請求的工具或技術(shù):

  • Fetch:一種現(xiàn)代化的網(wǎng)絡(luò)請求方法,通過使用 Promise 處理異步操作,簡潔而直觀地發(fā)送HTTP請求、處理響應,并支持各種功能和API,如設(shè)置請求頭、傳遞參數(shù)、處理流數(shù)據(jù)、上傳下載文件等。
  • Axios:一個基于Promise的現(xiàn)代化HTTP客戶端,是目前最流行的 HTTP 客戶端,可以在瀏覽器和Node.js環(huán)境中發(fā)送HTTP請求,并具有攔截請求和響應、支持并發(fā)請求、提供豐富的API等功能。
  • Ajax:通過在瀏覽器和服務器之間進行異步通信,實現(xiàn)部分頁面更新和動態(tài)交互,提升用戶體驗;可以在不重新加載整個頁面的情況下,通過JavaScript發(fā)送HTTP請求到服務器,并處理服務器返回的數(shù)據(jù);減少帶寬消耗,提高頁面加載速度;提高用戶交互性,實現(xiàn)更多的動態(tài)效果和實時更新。
  • XHR:一種在瀏覽器中用于與服務器進行異步通信的API,通過發(fā)送HTTP請求并處理服務器返回的數(shù)據(jù),實現(xiàn)異步獲取各種格式的數(shù)據(jù)(如XML、JSON、HTML等),以實現(xiàn)頁面的無刷新更新和動態(tài)交互。

下面就來看看這些技術(shù)都是怎么用的,以及都有什么特點!

2、XHR

XMLHttpRequest 是一個內(nèi)置的 JavaScript 對象,XMLHttpRequest(XHR)對象用于與服務器交互。通過 XMLHttpRequest 可以在不刷新頁面的情況下請求特定 URL,獲取數(shù)據(jù)。這允許網(wǎng)頁在不影響用戶操作的情況下,更新頁面的局部內(nèi)容。

XMLHttpRequest 在 AJAX 編程中被大量使用。盡管名稱包含XML,XMLHttpRequest 也可以用于獲取任何類型的數(shù)據(jù),而不僅僅是 XML。它甚至支持 HTTP 以外的協(xié)議(包括 file:// 和 FTP)。

XMLHttpRequest 存在一些缺點:

  • 語法復雜性:使用原始的 XMLHttpRequest 進行復雜的 AJAX 請求需要編寫更多的代碼,并手動處理狀態(tài)管理、錯誤處理等方面的邏輯。相比之下,Axios 和 Fetch API 提供了更簡單和直觀的語法,使得發(fā)送和處理 HTTP 請求更加方便。
  • 功能限制:XHR 提供的功能相對較少,需要手動設(shè)置請求頭、處理超時、取消請求等。而 Axios 和 Fetch API 提供了更豐富的功能,如攔截請求和響應、自動轉(zhuǎn)換數(shù)據(jù)格式、請求取消等。
  • XSRF(跨站請求偽造)保護:在 Axios 中,可以通過設(shè)置 withCredentials 選項來自動處理 XSRF 保護。然而,在 XMLHttpRequest 和 Fetch API 中,需要手動設(shè)置請求頭來實現(xiàn)類似的保護。
  • 錯誤處理:XHR 的錯誤處理較為繁瑣,需要在回調(diào)函數(shù)中進行錯誤判斷。而 Axios 和 Fetch API 使用 Promise 和 async/await 語法,能夠更便捷地處理請求和響應的錯誤。
  • 僅限于瀏覽器環(huán)境:XMLHttpRequest 是瀏覽器提供的 API,因此只能在瀏覽器環(huán)境中使用,無法在其他環(huán)境中(如服務器端)直接使用。

請求步驟

使用 XMLHttpRequest 發(fā)送請求的步驟如下:

  1. 創(chuàng)建XMLHttpRequest對象:
let xhr = new XMLHttpRequest();
  1. 設(shè)置請求參數(shù):
xhr.open('GET', 'https://example.com/api/data', true);
  1. 設(shè)置請求頭(可選):
xhr.setRequestHeader('Content-Type', 'application/json');
  1. 監(jiān)聽狀態(tài)變化:
xhr.onreadystatechange = () => {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      // 請求成功,處理響應
      console.log(xhr.responseText);
    } else {
      // 請求失敗
      console.error('請求失敗');
    }
  }
};
  1. 發(fā)送請求:
xhr.send();

完整代碼如下:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);

xhr.onreadystatechange = () => {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      // 請求成功,處理響應
      console.log(xhr.responseText);
    } else {
      // 請求失敗
      console.error('請求失敗');
    }
  }
};

xhr.send();

這里創(chuàng)建了一個XMLHttpRequest對象,并使用open()方法設(shè)置了一個GET請求類型和URL。然后,通過監(jiān)聽onreadystatechange事件來判斷請求的狀態(tài)并處理響應。當readyState為4時,表示請求已完成,此時可以通過status屬性判斷請求是否成功(200表示成功)。如果成功,可以通過responseText屬性獲取服務器返回的數(shù)據(jù)進行處理。如果失敗,將到控制臺輸出錯誤信息。

open

XMLHttpRequest 的 open() 方法用于初始化一個請求。open() 方法接受三個必填參數(shù)和一個可選參數(shù),它們是:

  1. method: 表示請求的 HTTP 方法,例如 GET、POST、PUT 等。
xhr.open("GET", "https://example.com/api/data", true);
  1. url: 表示請求的 URL 地址。
xhr.open("GET", "https://example.com/api/data", true);
  1. async: 表示請求是否異步執(zhí)行,即是否使用異步模式。默認為 true,表示異步執(zhí)行;false 表示同步執(zhí)行。
javascriptCopy Codexhr.open("GET", "https://example.com/api/data", true);
  1. username (可選): 表示用于進行 HTTP 認證的用戶名。
xhr.open("GET", "https://example.com/api/data", true, "username");
  1. password (可選): 表示用于進行 HTTP 認證的密碼。
xhr.open("GET", "https://example.com/api/data", true, "username", "password");

綜合起來,open() 方法的完整語法如下:

xhr.open(method, url, async, username, password);

請求頭和響應頭

可以使用 setRequestHeader() 方法設(shè)置 XMLHttpRequest 的請求頭。這個方法接受兩個參數(shù):頭字段的名稱和值。

xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Authorization", "Bearer token123");

這里使用 setRequestHeader() 方法設(shè)置了兩個請求頭:Content-Type 和 Authorization。第一個參數(shù)是頭字段的名稱,第二個參數(shù)是頭字段的值。

可以使用 getResponseHeader() 方法或者 getAllResponseHeaders() 方法來獲取 XMLHttpRequest 的響應頭。

  • getResponseHeader():通過指定頭字段的名稱,可以獲取指定的響應頭字段的值。
const contentType = xhr.getResponseHeader("Content-Type");

這里使用 getResponseHeader() 方法獲取了名為 Content-Type的響應頭字段的值。

  • getAllResponseHeaders()** **:該方法返回一個包含所有響應頭信息的字符串。
const headers = xhr.getAllResponseHeaders();

這里使用 getAllResponseHeaders() 方法獲取了所有響應頭信息,并將其存儲在名為 headers 的變量中。

這里返回的 headers 是一個包含所有響應頭信息的字符串。該字符串中每一行表示一個響應頭字段,具有以下形式:

HeaderName: HeaderValue

例如,如果響應頭中包含 Content-Type 和 Authorization 字段,那么返回的 headers 字符串可能如下所示:

Content-Type: application/json
Authorization: Bearer token123

可以使用適當?shù)姆椒ǎㄈ缱址馕觯⑦@個字符串進行進一步處理,以獲取特定的響應頭字段的名稱和值。

注意,要在調(diào)用 open() 方法之后、發(fā)送請求之前使用 setRequestHeader() 方法來設(shè)置請求頭,以確保設(shè)置能夠生效。同樣,要在接收到響應之后才能使用 getResponseHeader() 或 getAllResponseHeaders() 來獲取響應頭信息。

readyState

上面示例中的 readyState 是 XMLHttpRequest 對象的一個屬性,用于表示請求的狀態(tài)。該屬性有以下五種可能的取值:

  1. 0 (未初始化): XMLHttpRequest 對象已創(chuàng)建,但尚未調(diào)用 open 方法。
  2. 1 (載入中): open 方法已調(diào)用,但尚未調(diào)用 send 方法。
  3. 2 (載入完成): send 方法已調(diào)用,并且響應頭和響應狀態(tài)已經(jīng)可用。
  4. 3 (交互中): 正在接收響應數(shù)據(jù),此時部分響應內(nèi)容可能已經(jīng)可以訪問了。
  5. 4 (完成): 響應數(shù)據(jù)接收完成,整個請求過程已經(jīng)完全結(jié)束。

通常情況下,我們主要關(guān)注 readyState 為 4 的狀態(tài),即請求完成狀態(tài)。在這個狀態(tài)下,我們可以通過檢查 status 屬性來獲取請求的結(jié)果(比如響應狀態(tài)碼),并通過 responseText 或 responseXML 屬性來獲取服務器返回的數(shù)據(jù)。

注意,readyState 屬性是只讀的,我們不能直接修改它的值。它會在請求過程中自動更新,我們可以通過監(jiān)聽 readystatechange 事件來進行相應的處理。

status

status 是 XMLHttpRequest 對象的一個屬性,用于表示 HTTP 狀態(tài)碼。 HTTP 狀態(tài)碼是服務器對請求處理的結(jié)果進行響應的標準化數(shù)字代碼。常見的一些 HTTP 狀態(tài)碼包括:

  • 200 OK:表示請求成功并返回所請求的數(shù)據(jù)。
  • 201 Created:表示請求成功并在服務器上創(chuàng)建了新資源。
  • 204 No Content:表示請求成功,但響應中無返回的內(nèi)容。
  • 400 Bad Request:表示請求有語法錯誤或參數(shù)錯誤,服務器無法理解。
  • 401 Unauthorized:表示請求未經(jīng)授權(quán),需要用戶進行身份驗證。
  • 403 Forbidden:表示服務器拒絕請求,通常是因為請求的資源沒有訪問權(quán)限。
  • 404 Not Found:表示請求的資源不存在。
  • 500 Internal Server Error:表示服務器內(nèi)部發(fā)生錯誤,無法完成請求。

在使用 XMLHttpRequest 發(fā)送請求后,可以通過檢查 status 屬性來獲取服務器對請求的響應狀態(tài)碼,并根據(jù)不同的狀態(tài)碼進行相應的處理。

事件屬性

XMLHttpRequest (XHR) 對象具有以下常用的事件屬性:

  1. onreadystatechange: 當 readyState 屬性發(fā)生變化時觸發(fā)該事件??梢允褂?nbsp;xhr.onreadystatechange 屬性來指定處理狀態(tài)變化的回調(diào)函數(shù)。在每次狀態(tài)變化時都會觸發(fā)該事件,可以通過檢查 xhr.readyState 屬性來確定當前的狀態(tài)。
xhr.onreadystatechange = () => {
  if(xhr.readyState === 4) {
    // 請求已完成
    if(xhr.status === 200) {
      // 請求成功
    } else {
      // 請求失敗
    }
  } else {
    // 請求進行中
  }
};
  1. onload: 當請求成功完成并且響應數(shù)據(jù)完全加載時觸發(fā)該事件。可以使用 xhr.onload 屬性來指定處理成功加載的回調(diào)函數(shù)。通常在這個事件中獲取和處理響應數(shù)據(jù)。
xhr.onload = () => {
  // 獲取和處理響應數(shù)據(jù)
  const responseData = JSON.parse(xhr.responseText);
  // 其他操作...
};
  1. onerror: 當請求發(fā)生錯誤時觸發(fā)該事件。可以使用 xhr.onerror 屬性來指定處理錯誤的回調(diào)函數(shù)。常見的錯誤包括網(wǎng)絡(luò)錯誤、無法完成請求等。
xhr.onerror = () => {
  // 處理錯誤邏輯
};
  1. onprogress: 在數(shù)據(jù)傳輸過程中持續(xù)觸發(fā),用于追蹤請求的進度??梢允褂?nbsp;xhr.onprogress 屬性來指定處理進度的回調(diào)函數(shù)。
xhr.onprogress = (event) => {
  // 處理進度邏輯
};
  1. ontimeout: 當請求超時時觸發(fā)該事件??梢允褂?nbsp;xhr.ontimeout 屬性來指定處理超時的回調(diào)函數(shù)。
xhr.ontimeout = () => {
  // 處理超時邏輯
};

responseType

responseType 是 XMLHttpRequest 對象的屬性,用于指定響應的數(shù)據(jù)類型。它決定了如何解析從服務器返回的響應數(shù)據(jù)。 常見的 responseType 值包括:

  1. "" (默認值): 表示響應的數(shù)據(jù)類型是字符串。
xhr.responseType = "";
  1. "text": 表示響應的數(shù)據(jù)類型是字符串。
xhr.responseType = "text";
  1. "json": 表示響應的數(shù)據(jù)類型是 JSON 對象,會自動將響應數(shù)據(jù)解析為 JavaScript 對象。
xhr.responseType = "json";
  1. "document": 表示響應的數(shù)據(jù)類型是 XML 文檔對象,會自動將響應數(shù)據(jù)解析為 XML 文檔對象。
xhr.responseType = "document";
  1. "arraybuffer": 表示響應的數(shù)據(jù)類型是 ArrayBuffer 對象,適用于二進制數(shù)據(jù)的傳輸和處理。
xhr.responseType = "arraybuffer";
  1. "blob": 表示響應的數(shù)據(jù)類型是 Blob 對象,適用于文件下載等場景。
xhr.responseType = "blob";

通過設(shè)置不同的 responseType 值,可以根據(jù)需要獲取不同類型的響應數(shù)據(jù)。注意,在設(shè)置 responseType 之前,最好在調(diào)用 open 方法之后、發(fā)送請求之前設(shè)置,以確保設(shè)置生效。

3、Ajax

AJAX(Asynchronous JavaScript and XML,異步 JavaScript 和 XML)是一種使用現(xiàn)有的網(wǎng)頁技術(shù)來創(chuàng)建異步請求和更新頁面內(nèi)容的方法。Ajax 本身不是一種技術(shù),而是一種將一些現(xiàn)有技術(shù)結(jié)合起來使用的方法,包括:HTML 或 XHTML、CSS、JavaScript、DOM、XML、XSLT、以及最重要的 XMLHttpRequest 對象。

當使用結(jié)合了這些技術(shù)的 Ajax 模型以后,網(wǎng)頁應用能夠快速地將增量更新呈現(xiàn)在用戶界面上,而不需要重載(刷新)整個頁面。這使得程序能夠更快地回應用戶的操作。Ajax 最吸引人的特性是它的“異步”性質(zhì),這意味著它可以與服務器通信、交換數(shù)據(jù)并更新頁面,而無需刷新頁面。

Ajax 是一種使用瀏覽器提供的 XMLHttpRequest 對象實現(xiàn)的技術(shù),用于在不刷新整個頁面的情況下進行異步請求和更新頁面內(nèi)容。可以說 Ajax 是基于瀏覽器提供的 XMLHttpRequest 對象來實現(xiàn)的。

以下是基于原生 JavaScript 的 AJAX 請求代碼示例:

// 創(chuàng)建 XMLHttpRequest 對象
const xhr = new XMLHttpRequest();

// 指定請求的方法和 URL
xhr.open('GET', 'api_url', true);  // 第三個參數(shù) true 表示異步請求

// 設(shè)置請求頭(如果需要)
xhr.setRequestHeader('Content-Type', 'application/json');  // 根據(jù)實際需求設(shè)置請求頭

// 注冊一個回調(diào)函數(shù)來處理響應
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4 && xhr.status === 200) {
    const response = JSON.parse(xhr.responseText);  // 處理響應數(shù)據(jù)
    // 在這里執(zhí)行相應的操作
    console.log(response);
  }
};

// 發(fā)送請求
xhr.send();

雖然 AJAX 是一種強大的技術(shù),但相對于 Axios 和 Fetch API,它有以下一些缺點:

  • 兼容性問題:AJAX 的兼容性相對較低,尤其在舊版本的瀏覽器中可能會出現(xiàn)問題。而 Axios 和 Fetch API 使用了更現(xiàn)代的 JavaScript 特性,具有更好的兼容性。
  • 代碼冗余:使用原生的 AJAX 需要編寫較多的代碼來處理不同的狀態(tài)碼、錯誤處理以及請求的拼裝等。而 Axios 和 Fetch API 提供了更簡潔和易用的接口,減少了代碼冗余。
  • 缺乏默認配置:AJAX 不提供默認的全局配置,如請求和響應攔截器、統(tǒng)一的錯誤處理等。而 Axios 和 Fetch API 支持全局配置,并且提供了更方便的攔截器機制。
  • 功能限制:AJAX 在處理跨域請求時需要注意添加額外的處理,比如設(shè)置 CORS 頭部信息或者使用 JSONP。而 Axios 和 Fetch API 提供了更直接的方式來處理跨域請求。
  • 可讀性較差:由于 AJAX 使用的是回調(diào)函數(shù)來處理異步請求,可能會導致代碼邏輯比較復雜,可讀性較差。而 Axios 和 Fetch API 使用的是 Promise 或 async/await,使代碼結(jié)構(gòu)更加清晰易讀。

4、Fetch

Fetch 是一種用于進行網(wǎng)絡(luò)請求的現(xiàn)代 JavaScript API。它提供了一種簡單、靈活且功能強大的方式,用于從服務器獲取資源并處理響應。

Fetch API 在瀏覽器中原生支持,并且以 Promise 為基礎(chǔ),使得異步請求更加直觀和易用。使用 Fetch API,可以執(zhí)行各種類型的請求(如 GET、POST、PUT、DELETE 等),發(fā)送請求時可以設(shè)置請求頭、請求參數(shù),以及處理響應數(shù)據(jù)。

與傳統(tǒng)的 AJAX 相比,F(xiàn)etch API 具有以下優(yōu)點:

  • Promise 支持:Fetch API 使用 Promise 對象來處理異步操作,使得處理異步請求的流程更加清晰、易于閱讀和編寫。
  • 更簡潔的 API:Fetch API 提供了一個簡潔的 API,使發(fā)送請求變得更加直觀和簡單,同時提供了豐富的配置選項(如設(shè)置請求頭、請求參數(shù)等)。
  • 內(nèi)置的 JSON 解析:在處理響應時,F(xiàn)etch API 內(nèi)置了對 JSON 數(shù)據(jù)的解析,無需手動進行解析操作。
  • 更好的錯誤處理:Fetch API 使用了更全面的錯誤處理機制,允許通過檢查響應狀態(tài)碼來確定請求是否成功,并以不同的方式處理錯誤。

fetch()

Fetch API 提供了一個全局的 fetch() 方法,該方法提供了一種簡單、邏輯的方式來通過網(wǎng)絡(luò)異步獲取資源。

fetch() 方法的語法如下:

fetch(url, options)
  .then(response => {
    // 在這里處理響應
  })
  .catch(error => {
    // 在這里處理錯誤
  });

這里有兩個參數(shù):

  • url:請求的 URL 地址。
  • options(可選):一個包含請求選項的對象,可以指定請求的方法(method)、請求頭(headers)、請求體(body)等。

注意,fetch()默認使用的是 GET 請求,如果需要使用其他方法(如 POST、PUT 等),需要通過 options 參數(shù)進行設(shè)置。

fetch() 方法返回一個 Promise 對象,可以使用 .then() 方法來處理成功的響應,使用 .catch() 方法來處理錯誤的情況。

  • 在 .then() 中,可以訪問到 response 對象,進一步處理響應的內(nèi)容。
  • 在 .catch() 中,我們可以訪問到 error 對象,用于處理請求過程中的任何錯誤。

options 對象包含的屬性如下:

{
  method: 'POST', // *GET, POST, PUT, DELETE等
  mode: 'cors', // no-cors, *cors, same-origin
  cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
  credentials: 'same-origin', // include, *same-origin, omit
  headers: { 
    'Content-Type': 'application/json'
  },
  redirect: 'follow', // manual, *follow, error
  referrerPolicy: 'no-referrer', // no-referrer, *client
  body: JSON.stringify(data) 
   // body 數(shù)據(jù)類型必須與 "Content-Type" 請求頭匹配
}
  • method:請求方法,例如 GET、POST、PUT、DELETE 等。
  • mode:請求模式,可以是 no-cors、*cors、same-origin 等。
  • cache:緩存模式,可以是 default、no-cache、reload、force-cache、only-if-cached 等。
  • credentials:請求的憑證模式,可以是 include、*same-origin、omit 等。
  • headers:請求頭對象,用于設(shè)置請求頭的鍵值對。
  • redirect:重定向模式,可以是 manual、*follow、error 等。
  • referrerPolicy:引用頁面隱私設(shè)置,可以是 no-referrer、*client 等。
  • body:請求體數(shù)據(jù),必須與 "Content-Type" 請求頭指定的數(shù)據(jù)類型匹配。在示例中,使用JSON.stringify()將數(shù)據(jù)轉(zhuǎn)換為 JSON 字符串。

response

一旦獲取到響應(Response),返回的對象包含以下屬性:

  • response.body:一個簡單的 getter,提供了響應內(nèi)容的可讀流(ReadableStream)。
  • response.bodyUsed:一個布爾值,用于記錄響應體是否已經(jīng)被使用過。
  • response.headers:與響應相關(guān)聯(lián)的頭部信息對象。
  • response.ok:一個布爾值,指示響應是否成功。
  • response.redirected:指示響應是否是重定向結(jié)果的布爾值。
  • response.status:響應的狀態(tài)碼。
  • response.statusText:與狀態(tài)碼對應的狀態(tài)消息。
  • response.type:響應的類型。
  • response.url:響應的 URL。

我們可以使用 response.type 來確定響應的類型,并根據(jù)不同的類型采取相應的處理方法:

fetch(url)
  .then(response => {
    // 檢查響應狀態(tài)碼
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    // 定義一個響應類型與解析方法的映射關(guān)系
    const responseTypes = new Map([
      ['json', () => response.json()],
      ['text', () => response.text()],
      ['formData', () => response.formData()],
      ['blob', () => response.blob()],
      ['arrayBuffer', () => response.arrayBuffer()]
    ]);
    // 根據(jù)響應類型選擇相應的解析方法
    const parser = responseTypes.get(response.type);
    if (parser) {
      return parser();
    } else {
      throw new Error('Unsupported response type');
    }
  })
  .then(data => {
    // 處理數(shù)據(jù)
    console.log(data);
  })
  .catch(error => {
    // 處理錯誤情況
    console.error('Error:', error);
  });

Response 對象提供了 5 個方法,用于從 HTTP 響應中獲取不同類型的數(shù)據(jù):

  • response.json():將響應體解析為 JSON 對象。如果響應的 Content-Type 是 application/json,則使用此方法。
  • response.text():將響應體解析為文本字符串。如果響應的 Content-Type 是純文本類型,如 text/plain 或 text/html,則使用此方法。
  • response.formData():將響應體解析為 FormData 對象。如果響應的 Content-Type 是 multipart/form-data,則使用此方法。FormData 通常用于上傳文件或提交表單數(shù)據(jù)。
  • response.blob():將響應體解析為 Blob 對象。Blob 對象表示二進制大對象,可以是圖像、音頻、視頻等類型的數(shù)據(jù)。
  • response.arrayBuffer():將響應體解析為 ArrayBuffer 對象。ArrayBuffer 是一種表示二進制數(shù)據(jù)的固定長度緩沖區(qū)。

這些方法返回一個 Promise,當解析完成時,Promise 將被解析為相應的數(shù)據(jù)類型。

請求頭和響應頭

fetch 函數(shù)的請求頭包含在發(fā)起 HTTP 請求時發(fā)送給服務器的信息,用于傳遞額外的參數(shù)和配置。可以使用 headers 對象來設(shè)置和操作請求頭。常見的請求頭字段包括:

  • Content-Type:指定請求體的格式類型,如 application/json、application/x-www-form-urlencoded 等。
  • Authorization:用于身份驗證,通常與 Token 或用戶名密碼一起使用。
  • Accept:指定客戶端所能接受的響應數(shù)據(jù)類型。
  • User-Agent:標識發(fā)起請求的用戶代理(瀏覽器或應用程序)的信息。

在 fetch 函數(shù)中可以通過第二個參數(shù)進行配置,其中可以指定請求頭:

fetch(url, {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token123'
  }
})
  .then(response => {
    // 處理響應
  })
  .catch(error => {
    // 處理錯誤
  });

響應頭是服務器在響應 HTTP 請求時發(fā)送給客戶端的頭部信息。可以通過 Response 對象的 headers 屬性訪問響應頭。常見的響應頭字段包括:

  • Content-Type:指定響應體的格式類型。
  • Set-Cookie:設(shè)置或修改客戶端的 Cookie。
  • Cache-Control:控制緩存的行為,如 no-cache、max-age 等。
  • Content-Disposition:指定響應的內(nèi)容該如何展示(如文件的下載)。

在處理 fetch 返回的 Response 對象時,可以通過調(diào)用 response.headers.get('Header-Name') 方法來獲取特定的響應頭字段的值。

fetch(url)
  .then(response => {
    const contentType = response.headers.get('Content-Type');
    // 其他處理邏輯
  })
  .catch(error => {
    // 處理錯誤
  });

錯誤處理

除了可以使用 catch() 來處理錯誤之外,與使用其他異步操作一樣,我們也可以使用 async/await 來處理異步請求,使代碼更加簡潔和易讀:

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    if (response.ok) {
      const data = await response.json();
      console.log(data); // 處理解析后的數(shù)據(jù)
    } else {
      throw new Error('請求失敗');
    }
  } catch (error) {
    console.log(error); // 處理錯誤
  }
}

fetchData();

取消請求

在標準的 Fetch API 中,沒有提供直接取消 Fetch 請求的內(nèi)置方法。但是,可以使用以下方法來模擬或?qū)崿F(xiàn)取消 Fetch 請求的效果。

使用 AbortController 和 AbortSignal:這是一種較新的瀏覽器特性,用于生成可以取消請求的信號??梢詣?chuàng)建一個 AbortController對象,然后將其關(guān)聯(lián)到 Fetch 請求中,當需要取消請求時,調(diào)用 AbortController 的 abort()方法:

// 創(chuàng)建 AbortController 和關(guān)聯(lián)的 signal
const abortController = new AbortController();
const signal = abortController.signal;

// 發(fā)起 Fetch 請求,并將 signal 傳遞給 fetch 函數(shù)
fetch(url, { signal })
  .then(response => {
    // 處理響應
  })
  .catch(error => {
    if (error.name === 'AbortError') {
      // 請求已被取消
    } else {
      // 處理其他錯誤
    }
  });

// 當需要取消請求時,調(diào)用 abort() 方法
abortController.abort();

瀏覽器兼容

目前,主流瀏覽器都支持 Fetch API:

圖片圖片

5、Axios

Axios 是一個基于 Promise 網(wǎng)絡(luò)請求庫,用于在瀏覽器和 Node.js 中進行 HTTP 請求。在服務端它使用原生 node.js http 模塊, 而在客戶端 (瀏覽端) 則使用 XMLHttpRequests。Axios 是目前最流行的 HTTP 請求庫,其 npm 每周下載量達到了 4500w+。

Axios 庫具有以下特點:

  • 瀏覽器和 Node.js:Axios 可在瀏覽器和 Node.js 環(huán)境中使用,可以在不同的平臺上執(zhí)行 HTTP 請求。
  • Promise API:Axios 使用 Promise API 進行異步操作,能夠更輕松地處理異步請求和響應。
  • 請求攔截和響應攔截:可以通過攔截器,在請求發(fā)送之前或響應返回之后對請求進行全局性或個性化的變換和處理。可以在請求或響應的不同階段添加公共的請求頭、驗證身份、處理錯誤等。
  • 取消請求:Axios 允許取消未完成的請求,以避免無效的請求,并減輕服務器的負擔。取消請求可以通過創(chuàng)建取消令牌、使用取消令牌進行請求配置或者在攔截器中中斷請求來實現(xiàn)。
  • 并發(fā)請求:Axios 提供了執(zhí)行多個并發(fā)請求的能力,可以同時發(fā)起多個請求,并在所有請求完成后進行處理。
  • 自動轉(zhuǎn)換數(shù)據(jù):Axios 可以自動將請求和響應的數(shù)據(jù)進行格式轉(zhuǎn)換,包括 JSON、URL 編碼等。無需手動處理數(shù)據(jù)轉(zhuǎn)換的過程。
  • 錯誤處理機制:當請求過程中出現(xiàn)錯誤時,Axios 會返回詳細的錯誤信息,包括 HTTP 錯誤狀態(tài)碼、錯誤描述等??梢愿鶕?jù)需要對這些錯誤進行處理和顯示。
  • 簡潔的 API:Axios 的 API 設(shè)計簡潔易用,具有直觀的方法命名和參數(shù)配置。可以輕松地使用 Axios 進行 GET、POST、PUT、DELETE 等常見的 HTTP 請求。

可以通過以下命令來安裝 Axios:

// 使用 npm 安裝
npm install axios
// 使用 yarn 安裝
yarn add axios

下面來進行一個簡單的 get 請求:

axios.get('https://api.example.com/data')
  .then(response => {
    // 處理成功響應
    console.log(response.data);
  })
  .catch(error => {
    // 處理錯誤
    console.error(error);
  });

這里使用 axios.get 方法發(fā)起了一個 GET 請求,并將請求的 URL 作為參數(shù)傳遞給該方法。然后使用 Promise 的 .then 方法處理成功響應,并通過 response.data 獲取響應數(shù)據(jù)。如果請求失敗,可以通過 Promise 的 .catch 方法捕獲錯誤。

請求方法

axios 支持通過簡寫方式來執(zhí)行不同類型的請求:

  • axios.request(config)
  • axios.get(url[, config])
  • axios.delete(url[, config])
  • axios.head(url[, config])
  • axios.options(url[, config])
  • axios.post(url[, data[, config]])
  • axios.put(url[, data[, config]])
  • axios.patch(url[, data[, config]])

對于這些方法,第一個參數(shù)是請求的 URL,config 和 data 分別是請求的配置項和請求參數(shù),這兩個參數(shù)都是可選的。例如,下面是一個 post 請求:

const options = {
  headers: {'X-Custom-Header': 'value'}
};

axios.post('/save', { a: 10 }, options)
  .then(response => {
    // 處理成功響應
    console.log(response.data);
  })
  .catch(error => {
    // 處理錯誤
    console.error(error);
  });

當作為第二個參數(shù)傳遞給 axios.post 函數(shù)時,Axios 會自動將 JavaScript 對象序列化為 JSON。 這樣就無需將 POST 正文序列化為 JSON。Axios 還會自動將 Content-Type 請求頭設(shè)置為 application/json。

多個請求

在 Axios 中,可以使用 axios.all 和 axios.spread 來處理多個并發(fā)的請求:

const axios = require('axios');

// 創(chuàng)建多個請求
const request1 = axios.get('https://api.example.com/data1');
const request2 = axios.get('https://api.example.com/data2');

// 并發(fā)發(fā)送多個請求
axios.all([request1, request2])
  .then(axios.spread((response1, response2) => {
    // 處理各個請求的響應
    console.log(response1.data);
    console.log(response2.data);
  }))
  .catch(error => {
    // 處理錯誤
    console.error(error);
  });

可以看到,在 .then 方法中使用了 axios.spread 函數(shù)將多個請求的響應結(jié)果進行解構(gòu),通過多個參數(shù)分別接收各個請求的響應??梢愿鶕?jù)實際情況命名這些參數(shù),并通過 response1.data、response2.data 等方式獲取各個請求的響應數(shù)據(jù)。

請求攔截、響應攔截

在 Axios 中,可以使用 transformRequest 方法在請求發(fā)送之前對請求數(shù)據(jù)進行轉(zhuǎn)換和處理,它是一個請求攔截器,是一個可選的函數(shù)。

transformRequest 函數(shù)接收兩個參數(shù):requestData 和 requestHeaders。其中,requestData 是要發(fā)送的請求數(shù)據(jù),requestHeaders 是要發(fā)送的請求頭信息??梢栽?nbsp;transformRequest 函數(shù)內(nèi)部對這些參數(shù)進行修改,并將修改后的值返回。返回的結(jié)果將作為實際發(fā)送請求的數(shù)據(jù)。

axios({
  url: 'https://api.example.com/data',
  method: 'post',
  data: {
    id: 12345,
    name: 'John Doe'
  },
  transformRequest: (data, headers) => {
    // 對請求數(shù)據(jù)進行轉(zhuǎn)換和處理
    const modifiedData = { ...data }; // 復制原始數(shù)據(jù)

    // 修改數(shù)據(jù)或添加額外字段
    modifiedData.extraField = 'Extra Value';

    // 修改請求頭信息
    headers['Content-Type'] = 'application/json';

    return JSON.stringify(modifiedData); // 返回處理后的數(shù)據(jù)
  }
})
  .then(response => {
    // 處理成功響應
    console.log(response.data);
  })
  .catch(error => {
    // 處理錯誤
    console.error(error);
  });

這里使用 Axios 發(fā)起了一個 POST 請求。通過傳遞包含 transformRequest 函數(shù)的配置對象來定義請求。在 transformRequest 函數(shù)內(nèi)部,復制了原始的請求數(shù)據(jù) data,并進行了一些修改和處理,如添加了額外的字段和修改了請求頭信息。最終,將修改后的數(shù)據(jù)以 JSON 字符串的形式返回。Axios 將使用 transformRequest 函數(shù)返回的結(jié)果作為實際發(fā)送請求的數(shù)據(jù)。

除了可以對請求進行攔截之外,Axios 還支持對響應進行攔截,對響應數(shù)據(jù)進行轉(zhuǎn)換和處理??梢酝ㄟ^ transformResponse 響應攔截器來實現(xiàn)。該函數(shù)接收一個參數(shù):responseData,它是從服務器接收到的原始響應數(shù)據(jù)??梢栽?nbsp;transformResponse 函數(shù)內(nèi)部對這個參數(shù)進行修改,并將修改后的值返回。返回的結(jié)果將作為實際處理響應的數(shù)據(jù)。

axios.get('https://api.example.com/data', {
  transformResponse: (data) => {
    // 對響應數(shù)據(jù)進行轉(zhuǎn)換和處理
    const parsedData = JSON.parse(data); // 解析 JSON 字符串

    // 修改數(shù)據(jù)或添加額外字段
    parsedData.extraField = 'Extra Value';

    return parsedData; // 返回處理后的數(shù)據(jù)
  }
})
  .then(response => {
    // 處理成功響應
    console.log(response.data);
  })
  .catch(error => {
    // 處理錯誤
    console.error(error);
  });

這里使用 Axios 發(fā)起了一個 GET 請求,并通過傳遞包含 transformResponse 函數(shù)的配置對象來定義請求。在 transformResponse 函數(shù)內(nèi)部,對從服務器接收到的響應數(shù)據(jù) data 進行了一些修改和處理,如解析 JSON 字符串,添加了額外的字段。最終將修改后的數(shù)據(jù)返回。

攔截請求和響應

Axios 中,可以使用攔截器來攔截請求和響應,并在其被發(fā)送或接收之前進行一些額外的處理,可以通過 axios.interceptors 對象來添加攔截器。

// 添加請求攔截器
axios.interceptors.request.use(config => {
  // 在發(fā)送請求之前做一些處理
  console.log('請求攔截器');

  // 修改請求配置
  config.headers['Authorization'] = 'Bearer token';

  return config;
}, error => {
  // 處理請求錯誤
  console.error('請求出錯:', error);
});

// 添加響應攔截器
axios.interceptors.response.use(response => {
  // 在接收到響應數(shù)據(jù)之前做一些處理
  console.log('響應攔截器');

  // 修改響應數(shù)據(jù)
  response.data = { ...response.data, extraField: 'Extra Value' };

  return response;
}, error => {
  // 處理響應錯誤
  console.error('響應出錯:', error);
});

// 發(fā)送請求
axios.get('https://api.example.com/data')
  .then(response => {
    // 處理成功響應
    console.log(response.data);
  })
  .catch(error => {
    // 處理請求或響應錯誤
    console.error(error);
  });

這里首先使用 axios.interceptors.request.use 方法添加了一個請求攔截器。該攔截器在發(fā)送請求之前被調(diào)用,并接收請求配置對象 config 作為參數(shù)??梢詫φ埱笈渲眠M行修改,如添加請求頭信息。最后,要確保返回修改后的配置對象。

接下來,使用 axios.interceptors.response.use 方法添加了一個響應攔截器。該攔截器在接收到響應數(shù)據(jù)之前被調(diào)用,并接收響應對象 response 作為參數(shù)??梢詫憫獢?shù)據(jù)進行修改,如添加額外的字段。同樣,要確保返回修改后的響應對象。

客戶端支持 XSRF 防護

跨站請求偽造(簡稱 XSRF)是一種攻擊 Web 應用的方法,其中攻擊者將自己偽裝成合法且受信任的用戶,以影響應用程序與用戶瀏覽器之間的交互。 有很多方法可以執(zhí)行此類攻擊,包括 XMLHttpRequest。

幸運的是,Axios 通過允許在發(fā)出請求時嵌入額外的身份驗證數(shù)據(jù)來防止 XSRF。 這使得服務器能夠發(fā)現(xiàn)來自未經(jīng)授權(quán)的位置的請求。以下是使用 Axios 完成此操作的方法:

const options = {
  method: 'post',
  url: '/login',
  xsrfCookieName: 'XSRF-TOKEN',
  xsrfHeaderName: 'X-XSRF-TOKEN',
};

axios(options)
  .then(response => {
    // 處理成功響應
    console.log(response.data);
  })
  .catch(error => {
    // 處理請求錯誤
    console.error(error);
  });

這里有兩個 xsrf 相關(guān)的屬性:

  • xsrfCookieName: 'XSRF-TOKEN':用于跨站請求偽造(XSRF/CSRF)保護的配置選項之一。它指定了存儲 XSRF 令牌的 cookie 的名稱。XSRF 令牌用于防止惡意網(wǎng)站發(fā)起對已驗證用戶的請求。
  • xsrfHeaderName: 'X-XSRF-TOKEN':用于跨站請求偽造(XSRF/CSRF)保護的配置選項之一。它指定了包含 XSRF 令牌的請求頭的名稱。服務器端可以通過檢查該請求頭來驗證請求的合法性。

請求進度

Axios 的另一個有趣的功能是能夠監(jiān)控請求的進度,這在下載或上傳大文件時特別有用,可以使用 onUploadProgress 和 onDownloadProgress 兩個配置選項來實現(xiàn)。

對于上傳進度,可以使用 onUploadProgress 配置選項。它會在上傳數(shù)據(jù)時觸發(fā),并提供關(guān)于上傳進度的信息。

axios.post('/upload', data, {
  onUploadProgress: progressEvent => {
    const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
    console.log(`上傳進度:${percentCompleted}%`);
  },
})
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error(error);
  });

這里發(fā)送了一個 POST 請求,在配置選項中使用了 onUploadProgress。當數(shù)據(jù)上傳過程中觸發(fā)進度事件時,回調(diào)函數(shù)會被執(zhí)行。在回調(diào)函數(shù)中,我們計算出了已上傳數(shù)據(jù)的百分比,并將其打印出來。

對于下載進度,可以使用 onDownloadProgress 配置選項。它會在接收到響應數(shù)據(jù)時觸發(fā),并提供關(guān)于下載進度的信息。

axios.get('/download', {
  onDownloadProgress: progressEvent => {
    const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
    console.log(`下載進度:${percentCompleted}%`);
  },
})
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error(error);
  });

這里發(fā)送了一個 GET 請求,在配置選項中使用了 onDownloadProgress。當數(shù)據(jù)下載過程中觸發(fā)進度事件時,回調(diào)函數(shù)會被執(zhí)行。在回調(diào)函數(shù)中,我們計算出了已下載數(shù)據(jù)的百分比,并將其打印出來。

取消請求

在 Axios 中,可以使用取消令牌(cancel token)來取消請求。取消令牌是一個對象,它表示一個具體的取消操作,并允許在需要時中止請求。

// 創(chuàng)建一個取消令牌源
const CancelToken = axios.CancelToken;
const source = CancelToken.source();

// 發(fā)送請求
axios.get('/api/data', {
  cancelToken: source.token
})
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    if (axios.isCancel(error)) {
      console.log('請求已被取消:', error.message);
    } else {
      console.error(error);
    }
  });

// 取消請求
source.cancel('取消請求的原因');

這里,先創(chuàng)建了一個取消令牌源 source。然后,發(fā)送 GET 請求時將 cancelToken 配置選項設(shè)置為 source.token,即將取消令牌與該請求關(guān)聯(lián)起來。當需要取消請求時,調(diào)用 source.cancel() 方法,并傳入取消請求的原因作為參數(shù)。

在請求的 .catch() 方法中,我們使用 axios.isCancel(error) 來判斷捕獲的錯誤是否是一個已取消的請求。如果是取消請求導致的錯誤,則會打印出 '請求已被取消' 的提示信息。否則,將打印出其他類型的錯誤。

請求超時

可以使用 timeout 配置選項設(shè)置 Axios 請求的超時時間,這個選項指定了請求在多少毫秒后如果沒有得到響應就會超時。

axios.get('/api/data', {
  timeout: 5000 // 設(shè)置超時時間為5秒
})
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error(error);
  });

發(fā)送了一個 GET 請求,并在配置選項中設(shè)置了 timeout 為 5000 毫秒(即 5 秒)。如果請求在 5 秒內(nèi)沒有得到響應,就會觸發(fā)超時錯誤。在超時錯誤的情況下,請求會被自動取消,并且進入 .catch() 分支。您可以根據(jù)需要進行錯誤處理。

注意,如果不設(shè)置 timeout 選項,默認情況下 Axios 請求是沒有超時限制的。

6、小結(jié)

相對于 Fetch、XMLHttpRequest 和 Ajax,我還是更喜歡 Axios。它提供了簡潔易用的 API,統(tǒng)一的錯誤處理和攔截器支持,取消請求和超時處理功能,以及基于 Promise 的鏈式調(diào)用和跨瀏覽器兼容性。這些特性使得使用 Axios 更方便、高效,并提供更好的開發(fā)體驗。

責任編輯:武曉燕 來源: 前端充電寶
相關(guān)推薦

2011-01-19 11:10:30

2010-03-18 14:54:46

主流無線技術(shù)

2024-02-22 13:55:41

前端動畫庫

2009-03-24 10:04:03

GrailsAjaxJava

2010-07-14 13:38:51

Perl開發(fā)工具

2020-08-04 17:06:40

Merging Rebasing Git

2010-09-08 15:41:28

SIP協(xié)議棧

2014-01-07 17:08:02

Java開源框架

2010-08-25 16:12:34

職場

2017-09-10 14:29:03

眼力

2011-11-08 10:29:44

2021-03-15 21:07:17

IT行業(yè)薪酬薪水

2010-05-28 11:09:51

SVN功能

2023-05-26 15:53:48

MidjourneyAI圖像

2018-10-25 14:08:07

KubernetesGoogle

2019-03-29 08:25:21

JSONXML前端

2011-04-01 09:18:01

MRTGCactiZabbix

2010-04-21 12:54:46

Unix內(nèi)核

2012-08-15 09:26:54

虛擬化

2019-08-27 09:00:00

敏捷開發(fā)開發(fā)方法項目
點贊
收藏

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