fetch api 默认返回 promise 且需手动处理响应体、http 错误、请求头与 body 匹配、查询参数编码、认证信息及超时/取消等关键细节,否则易导致静默失败。

JavaScript 的 Fetch API 是浏览器原生提供的网络请求接口,用起来比老式的 XMLHttpRequest 更简洁、更符合现代异步编程习惯。它默认返回 Promise,天然支持 async/await,但有几个关键点必须手动处理——否则请求看似“发出去了”,实际却拿不到数据、捕获不到错误,甚至悄悄失败。
GET 请求:三步不能少
最常用的 GET 请求看似简单,实则容易漏掉关键环节:
- 调用
fetch(url)只得到一个Response对象,不是你要的数据 - 必须显式调用
.json()(或.text()、.blob())来读取响应体,这个方法本身也返回 Promise -
HTTP 错误状态(如 404、500)不会触发
catch,得靠response.ok或response.status主动判断
推荐写法(async/await 风格):
async function fetchUser(id) {
try {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const user = await res.json();
return user;
} catch (err) {
console.error('获取用户失败', err);
}
}
POST 请求:body 和 headers 必须配对
发 POST 最常出错的地方是格式不匹配。后端收不到数据,往往不是接口问题,而是前端没配对好:
- 传 JSON 数据:headers 加
'Content-Type': 'application/json',body 用JSON.stringify({ ... }) - 传表单数据(含文件):用
FormData实例当 body,不要手动设Content-Type,浏览器会自动生成带boundary的正确头 - 传 URL 编码数据:用
new URLSearchParams({ key: 'val' }).toString()构造 body,headers 可加'Content-Type': 'application/x-www-form-urlencoded'
示例(JSON 提交):
const data = { email: 'user@test.com', password: '123' };
fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
带认证或查询参数的 GET
登录态、权限控制等场景下,GET 请求也需要携带信息:
- 带 Token:通过
headers传Authorization,例如{ 'Authorization': 'Bearer abc123' } - 带查询参数:别手拼字符串,用
URLSearchParams自动编码,避免中文或特殊字符出错
示例(带参数和 Token):
const params = new URLSearchParams({ page: 1, limit: 10 });
const url = `/api/posts?${params}`;
fetch(url, {
headers: { 'Authorization': 'Bearer xyz789' }
}).then(r => r.json());
超时与取消:Fetch 本身不支持,得靠 AbortController
Fetch 没有内置 timeout 选项,网络卡住时会一直 pending。要实现超时或用户主动取消,需配合 AbortController:
- 创建控制器:
const controller = new AbortController() - 把
signal: controller.signal传入 fetch 配置 - 调用
controller.abort()即可中断请求(注意:Promise 不会自动 reject,需监听abort事件或在 catch 中判断err.name === 'AbortError')
简易超时封装示例:
function fetchWithTimeout(url, options = {}, timeout = 5000) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
return fetch(url, { ...options, signal: controller.signal })
.finally(() => clearTimeout(id));
}大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











