最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

fetch和axios區(qū)別的詳細(xì)對(duì)比舉例

 更新時(shí)間:2026年05月13日 09:59:31   作者:愛吃土豆絲呦  
在前端開發(fā)中,數(shù)據(jù)交互是非常重要的一部分,Axios和Fetch被廣泛用于與服務(wù)器進(jìn)行數(shù)據(jù)交換,這篇文章主要介紹了fetch和axios區(qū)別詳細(xì)對(duì)比的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、它們是什么

FetchAxios
類型瀏覽器原生 API(Node 18+ 也內(nèi)置)第三方庫
底層基于 Promise,原生實(shí)現(xiàn)瀏覽器基于 XMLHttpRequest,Node 端基于 http 模塊
體積0(原生)約 15KB(gzip 后約 5KB)
安裝無需安裝npm i axios

二、核心差異速查

特性FetchAxios
HTTP 錯(cuò)誤(4xx/5xx)是否進(jìn) catch? 不進(jìn),需手動(dòng)判斷 res.ok? 自動(dòng) reject
自動(dòng) JSON 解析? 需 res.json()? 自動(dòng)解析 response.data
請(qǐng)求/響應(yīng)攔截器? 無(需自己封裝)? 內(nèi)置
請(qǐng)求超時(shí)? 需配合 AbortController 手動(dòng)實(shí)現(xiàn)? timeout 配置項(xiàng)
請(qǐng)求取消? AbortController? AbortController / CancelToken(舊)
上傳/下載進(jìn)度?? 僅支持下載(ReadableStream);上傳需自己實(shí)現(xiàn)? onUploadProgress / onDownloadProgress
CSRF/XSRF 防護(hù)? 無? 內(nèi)置 xsrfCookieName
默認(rèn)攜帶 cookie? 默認(rèn)不帶(需 credentials: 'include'? 同源默認(rèn)帶,跨域需 withCredentials: true
自動(dòng)轉(zhuǎn)換請(qǐng)求體? 需手動(dòng) JSON.stringify? 自動(dòng)序列化
瀏覽器兼容現(xiàn)代瀏覽器,IE 不支持通過 XHR 兼容到 IE11
Node.js 支持Node 18+ 內(nèi)置全版本支持

三、詳細(xì)對(duì)比

1. 錯(cuò)誤處理

Fetch:HTTP 錯(cuò)誤狀態(tài)不會(huì)讓 Promise reject。

fetch('/api/user/999')
  .then(res => {
    // 即使是 404、500,這里依然會(huì)進(jìn)入 then
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return res.json();
  })
  .catch(err => console.error(err));
// 只有網(wǎng)絡(luò)斷開、CORS 失敗、請(qǐng)求被中止才會(huì)進(jìn) catch

Axios:HTTP 錯(cuò)誤自動(dòng)進(jìn) catch。

axios.get('/api/user/999')
  .then(res => console.log(res.data))
  .catch(err => {
    if (err.response) {
      // 服務(wù)器返回了非 2xx
      console.log(err.response.status, err.response.data);
    } else if (err.request) {
      // 請(qǐng)求發(fā)出但無響應(yīng)
    } else {
      // 配置錯(cuò)誤
    }
  });

2. 請(qǐng)求體與響應(yīng)體

Fetch:手動(dòng)序列化 + 手動(dòng)解析。

fetch('/api/user', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'Tom' }),
})
  .then(res => res.json())
  .then(data => console.log(data));

Axios:自動(dòng)處理。

axios.post('/api/user', { name: 'Tom' })
  .then(res => console.log(res.data));
// Content-Type 自動(dòng)設(shè)為 application/json,body 自動(dòng)序列化,data 自動(dòng)解析

3. 攔截器(Axios 殺手锏)

Axios:內(nèi)置請(qǐng)求/響應(yīng)攔截器,可統(tǒng)一加 token、統(tǒng)一處理錯(cuò)誤。

// 請(qǐng)求攔截器:每次請(qǐng)求自動(dòng)加 token
axios.interceptors.request.use(config => {
  config.headers.Authorization = `Bearer ${getToken()}`;
  return config;
});

// 響應(yīng)攔截器:401 自動(dòng)跳登錄頁
axios.interceptors.response.use(
  res => res.data,
  err => {
    if (err.response?.status === 401) location.href = '/login';
    return Promise.reject(err);
  }
);

Fetch:沒有攔截器,要么自己封裝一層,要么用 monkey-patch

const originalFetch = window.fetch;
window.fetch = async (url, options = {}) => {
  options.headers = { ...options.headers, Authorization: `Bearer ${getToken()}` };
  const res = await originalFetch(url, options);
  if (res.status === 401) location.href = '/login';
  return res;
};

4. 超時(shí)控制

Fetch:原生不支持,需 AbortController

const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 5000);

fetch('/api/data', { signal: controller.signal })
  .finally(() => clearTimeout(timer));

Axios:一行配置。

axios.get('/api/data', { timeout: 5000 });

5. 請(qǐng)求取消

Fetch:AbortController

const ctrl = new AbortController();
fetch('/api/data', { signal: ctrl.signal });
ctrl.abort(); // 取消

Axios:新版本同樣使用 AbortController(舊版本是 CancelToken,已廢棄)。

const ctrl = new AbortController();
axios.get('/api/data', { signal: ctrl.signal });
ctrl.abort();

6. 上傳進(jìn)度

Fetch:原生不支持(只能監(jiān)控下載,通過 ReadableStream)。

Axios:直接配置。

axios.post('/upload', formData, {
  onUploadProgress: (e) => {
    const percent = Math.round((e.loaded / e.total) * 100);
    console.log(`已上傳 ${percent}%`);
  },
});

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

Fetch:用 Promise.all。

const [user, posts] = await Promise.all([
  fetch('/api/user').then(r => r.json()),
  fetch('/api/posts').then(r => r.json()),
]);

Axios:同樣支持 Promise.all,舊版本另有 axios.all / axios.spread

const [user, posts] = await Promise.all([
  axios.get('/api/user'),
  axios.get('/api/posts'),
]);

8. 跨域與 Cookie

Fetch:默認(rèn)不發(fā)送 Cookie。

fetch('/api/data', { credentials: 'include' }); // 跨域攜帶
fetch('/api/data', { credentials: 'same-origin' }); // 同源攜帶(默認(rèn)在某些場景)

Axios:默認(rèn)同源帶 Cookie,跨域需配置。

axios.get('/api/data', { withCredentials: true });

9. 創(chuàng)建實(shí)例

Fetch:沒有實(shí)例概念,通常自己寫一個(gè)工廠函數(shù)。

Axios:內(nèi)置實(shí)例機(jī)制,方便配置不同 baseURL。

const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 5000,
  headers: { 'X-Custom': 'foo' },
});

api.get('/users');

四、Fetch 簡易封裝(接近 Axios 體驗(yàn))

async function request(url, options = {}) {
  const { timeout = 10000, baseURL = '', ...rest } = options;

  // 超時(shí)控制
  const ctrl = new AbortController();
  const timer = setTimeout(() => ctrl.abort(), timeout);

  // 自動(dòng) JSON
  if (rest.body && typeof rest.body === 'object') {
    rest.body = JSON.stringify(rest.body);
    rest.headers = { 'Content-Type': 'application/json', ...rest.headers };
  }

  try {
    const res = await fetch(baseURL + url, { ...rest, signal: ctrl.signal });
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return await res.json();
  } finally {
    clearTimeout(timer);
  }
}

// 使用
request('/api/user', { method: 'POST', body: { name: 'Tom' } });

五、如何選擇

場景推薦
簡單腳本、小項(xiàng)目、DemoFetch(零依賴)
中后臺(tái)、企業(yè)項(xiàng)目Axios(攔截器、錯(cuò)誤處理省心)
體積敏感(H5、小程序、SDK)Fetch + 簡單封裝
需要兼容 IEAxios
Node.js 服務(wù)端Axios(生態(tài)成熟),或 Node 18+ 原生 fetch
React Server Components / Next.jsFetch(與緩存機(jī)制集成更好)

六、總結(jié)一句話

Fetch 是底層標(biāo)準(zhǔn),Axios 是上層封裝。 一個(gè)項(xiàng)目要不要 Axios,本質(zhì)是問:"攔截器、自動(dòng) JSON、超時(shí)、錯(cuò)誤統(tǒng)一處理 —— 這些功能你愿不愿意自己寫?"

到此這篇關(guān)于fetch和axios區(qū)別的詳細(xì)對(duì)比舉例的文章就介紹到這了,更多相關(guān)fetch和axios區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

江山市| 含山县| 罗江县| 盐城市| 小金县| 宜昌市| 漠河县| 稷山县| 金塔县| 汉中市| 平远县| 江口县| 临桂县| 新干县| 江山市| 库尔勒市| 杭锦后旗| 安康市| 阆中市| 临漳县| 浠水县| 香河县| 马尔康县| 滨州市| 土默特左旗| 呼图壁县| 普宁市| 广德县| 雷波县| 德江县| 石林| 垫江县| 成安县| 乌拉特中旗| 鄂托克旗| 长乐市| 栾川县| 四川省| 遂昌县| 霍山县| 乌苏市|