Fetch API 与异步网络请求

7 阅读2分钟

上一期我们掌握了 async/await 的优雅写法,今天就把它真正用起来:
学习现代浏览器中最推荐的网络请求方式 —— Fetch API

Fetch 是 Promise 风格的网络请求 API,取代了古老的 XMLHttpRequest,成为目前前端获取数据的标准方式。

1. 最基础的 GET 请求

async function getUser() {
  try {
    const response = await fetch('https://api.example.com/users/123');
    
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    
    const user = await response.json();
    console.log('用户信息:', user);
    return user;
  } catch (error) {
    console.error('获取用户失败:', error);
  }
}

关键点:

  • fetch() 返回一个 Promise,resolve 后得到 Response 对象
  • response.ok 判断请求是否成功(状态码 200~299)
  • response.json() 也是返回 Promise,需要 await

2. 常用请求方式完整示例

// GET - 带查询参数
async function searchUsers(keyword) {
  const url = `https://api.example.com/users?q=${encodeURIComponent(keyword)}`;
  const response = await fetch(url);
  return response.json();
}

// POST - 创建资源
async function createPost(title, content) {
  const response = await fetch('https://api.example.com/posts', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({ title, content })
  });
  
  if (!response.ok) throw new Error('创建失败');
  return response.json();
}

// PUT - 更新资源
async function updateUser(id, data) {
  const response = await fetch(`https://api.example.com/users/${id}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data)
  });
  return response.json();
}

// DELETE
async function deletePost(id) {
  await fetch(`https://api.example.com/posts/${id}`, {
    method: 'DELETE'
  });
  // 通常 204 No Content,不需要 .json()
}

3. 实用技巧与最佳实践

场景推荐写法说明
超时控制使用 AbortController防止请求挂起太久
统一错误处理封装 fetch 函数统一处理 4xx/5xx 和网络错误
带凭证(cookie)credentials: 'include'跨域携带 cookie
防止缓存cache: 'no-store' 或添加时间戳开发调试或实时数据时常用
并发请求Promise.all + fetch同时请求多个接口
流式响应response.body.getReader()处理大文件或 SSE

超时示例(非常推荐)

async function fetchWithTimeout(url, timeout = 8000) {
  const controller = new AbortController();
  const id = setTimeout(() => controller.abort(), timeout);

  try {
    const response = await fetch(url, { signal: controller.signal });
    clearTimeout(id);
    return response;
  } catch (error) {
    clearTimeout(id);
    if (error.name === 'AbortError') {
      throw new Error('请求超时');
    }
    throw error;
  }
}

4. Fetch vs axios vs jQuery.ajax 对比(2025-2026 视角)

特性FetchaxiosjQuery.ajax
原生否(需引入)
Promise 支持原生原生 + 更多封装较老版本需转换
自动 JSON否(需手动 .json())部分支持
请求/响应拦截无(需自己实现)原生支持
超时处理需 AbortController内置 timeout 配置内置
取消请求AbortControllerCancelToken / AbortSignal较麻烦
浏览器兼容几乎全部现代浏览器所有(含旧版)所有
包体积0kb~13kb(gz)很大

结论
2026 年,大多数中大型项目仍然首选 axios(因为生态完善、拦截器好用),
所有新项目都应该优先掌握原生 Fetch,它是标准、轻量、无依赖的未来方向。

5. 小结

Fetch + async/await 是目前最“现代感”的网络请求组合方式:

  • 语法简洁
  • 原生无依赖
  • 与 Promise 生态无缝衔接
  • 支持所有现代特性(Abort、流、form-data 等)

下一期我们进入更进阶的内容:
高级异步:并发控制与性能优化
—— 如何优雅地处理 100 个并发请求?如何避免瀑布式请求?如何做请求节流?

我们下期见~

留言区互动:
你在实际项目中是用原生 Fetch 还是 axios 更多?
有没有遇到过“明明接口成功了却进 catch”的奇怪情况?😂