⚡ 编程实验室🏗️ HTML🎨 CSS⚡ JavaScript🐍 Python🗄️ SQL☕ Java⚛️ React💚 Vue🟢 Node.js⚙️ C语言🐘 PHP🐹 Go🔷 TypeScript🐬 MySQL🔧 C++🎯 C#🦀 Rust🅱️ Bootstrap💡 jQuery🎸 Django🍃 MongoDB👗 Sass🎪 Kotlin📊 R语言📋 XML📊 Excel🐘 PostgreSQL🐳 Docker🅰️ Angular🎮 游戏🏠 网站首页

JavaScript Fetch API 完全指南

从零掌握 Fetch API,学会 GET/POST/文件上传/错误处理/超时控制。 · 难度:入门 · +15XP

告别 XMLHttpRequest

在 Fetch 出现之前,前端发送 HTTP 请求用的是 XMLHttpRequest(简称 XHR)。它的 API 设计得……不太友好:

// XHR 写法(老方式)
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data');
xhr.onload = () => console.log(JSON.parse(xhr.responseText));
xhr.onerror = () => console.error('失败了');
xhr.send();

而 Fetch API 用 Promise 包装,写法简洁得多:

// Fetch 写法(现代方式)
fetch('https://api.example.com/data')
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.error('失败了', err));

GET 请求:获取数据

最基本的用法——从服务器拿数据:

async function getUsers() {
  const response = await fetch('https://jsonplaceholder.typicode.com/users');
  if (!response.ok) {
    throw new Error('HTTP Error: ' + response.status);
  }
  const users = await response.json();
  console.log(users); // [{id:1, name:'Leanne'}, ...]
}

关键点:response.ok 只在 HTTP 状态码 200-299 时为 true。Fetch 不会把 404 或 500 当作错误——你必须自己检查!

response 对象的常用方法

方法返回用途
response.json()Promise<Object>解析 JSON 响应体
response.text()Promise<string>读取纯文本
response.blob()Promise<Blob>读取图片/文件
response.formData()Promise<FormData>读取表单数据
response.statusnumber状态码(200/404/500)
response.okboolean状态码是否 200-299

POST 请求:发送数据

async function createUser(name, email) {
  const response = await fetch('https://api.example.com/users', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ name, email }),
  });
  const result = await response.json();
  console.log('创建成功:', result);
}

上传文件的正确方式

上传文件不要设 Content-Type,让浏览器自动处理 multipart/form-data 和 boundary:

async function uploadFile(file) {
  const formData = new FormData();
  formData.append('file', file);
  formData.append('folder', 'avatars');

const response = await fetch('/api/upload', { method: 'POST', body: formData, // 不用设 Content-Type! }); return response.json(); }

超时控制(Fetch 不自带超时)

Fetch 没有内置的超时机制,但你可以用 AbortController 实现:

async function fetchWithTimeout(url, timeoutMs = 5000) {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), timeoutMs);

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

取消请求

用户快速切换页面时,上一个请求可能还在进行中。用 AbortController 取消它:

const controller = new AbortController();

// 发起请求 fetch('/api/search?q=react', { signal: controller.signal });

// 用户输入了新关键词,取消上一个请求 controller.abort();

这在搜索框实时查询(debounce + abort)场景中非常实用。

实战:封装一个通用的请求函数

async function request(url, options = {}) {
  const defaultOptions = {
    headers: { 'Content-Type': 'application/json' },
    timeout: 10000,
  };

const mergedOptions = { ...defaultOptions, ...options }; const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), mergedOptions.timeout);

try { const response = await fetch(url, { ...mergedOptions, signal: controller.signal, });

if (!response.ok) { const errorBody = await response.text().catch(() => ''); throw new Error('HTTP ' + response.status + ': ' + errorBody.slice(0, 100)); }

const contentType = response.headers.get('content-type'); if (contentType && contentType.includes('application/json')) { return response.json(); } return response.text(); } finally { clearTimeout(timer); } }

// 使用 const users = await request('/api/users'); const newUser = await request('/api/users', { method: 'POST', body: JSON.stringify({ name: '小明' }), });

动手试试

  1. 基础练习:用 Fetch 从 https://jsonplaceholder.typicode.com/posts 获取数据,展示前 10 条标题
  2. 进阶应用:用上面封装的 request 函数,实现一个带超时和错误重试(失败后自动重试 3 次)的请求工具
  3. 项目实战:把你项目中现有的 axios 调用改成 Fetch,封装成和项目 API 风格一致的请求函数,保证错误处理逻辑不变

接下来学什么?

学会了 Fetch,下一课我们学习 JavaScript Promise 从入门到精通——理解 async/await 的底层原理、错误传播、并发控制。

📖 译自 MDN Web Docs Using the Fetch API (CC-BY-SA 2.5),有改编和扩充。

🚀 升级VIP
解锁全部课程+AI助手

🏆 学习排行

加载中...

📊 统计

📖 231 篇
0 完成
🔥 0