fetch默认不带cookie,需设credentials选项;404/500不触发catch,须检查response.ok;json解析失败需单独try-catch;超时与中断需用abortcontroller。

fetch 默认不带 cookie,跨域请求需显式配置
fetch 发起请求时默认不会携带 Cookie,即使同源也不行。这和传统 XMLHttpRequest 的行为不同,容易导致登录态丢失、鉴权失败等问题。
解决方法:在调用 fetch 时传入 credentials 选项:
-
credentials: 'include' —— 始终发送 Cookie(同源/跨域都发,但要求后端响应头含
Access-Control-Allow-Credentials: true) - credentials: 'same-origin' —— 默认值,仅同源时发 Cookie
- credentials: 'omit' —— 从不发送 Cookie
⚠️ 注意:若设为 'include',后端 CORS 配置必须明确允许凭据,且 Access-Control-Allow-Origin 不能为通配符 *,必须指定具体域名(如 https://example.com)。
fetch 不会因 HTTP 状态码报错,404/500 仍算“成功”
fetch 只在网络异常(断网、DNS 失败、请求被拦截)时 reject;而 404、500、401 等 HTTP 错误状态码,仍会进入 then 分支,容易误判为请求成功。
正确做法:手动检查 response.ok 或 response.status:
if (!response.ok) throw new Error(`${response.status} ${response.statusText}`)- 或封装统一的响应校验逻辑,避免每个请求重复写判断
示例:
fetch('/api/user')
.then(res => {
if (!res.ok) throw res;
return res.json();
})
.catch(err => {
if (err instanceof Response) {
// 处理 4xx/5xx
return err.json().then(data => Promise.reject({ status: err.status, ...data }));
}
// 处理网络错误等
console.error('网络异常', err);
});JSON 解析失败会抛出语法错误,需单独 try-catch
response.json() 是异步操作,且只要响应体不是合法 JSON(如返回了 HTML 错误页、空字符串、二进制流),就会立即 reject 一个 SyntaxError。
常见陷阱:把 .json() 和后续处理链在同一个 catch 中处理,导致无法区分是网络问题、HTTP 错误,还是 JSON 解析失败。
- 建议将
.json()单独包裹 try-catch,或用.text()先读取原始内容再安全解析 - 服务端返回非 JSON 内容(如调试时直接输出
var_dump(...))极易触发该错误
更健壮写法:
fetch('/api/data')
.then(res => {
if (!res.ok) throw { type: 'http', status: res.status };
return res.text(); // 先读文本,避免 json() 直接崩
})
.then(text => {
try {
return JSON.parse(text);
} catch (e) {
throw { type: 'json', raw: text, error: e.message };
}
})中断请求需靠 AbortController,原生 fetch 不支持 timeout
fetch 本身没有超时参数,也没有内置取消机制。长时间挂起的请求可能阻塞 UI 或造成资源浪费。
- 使用 AbortController 可主动中止请求(兼容性良好,现代浏览器均支持)
- 结合 setTimeout 可模拟超时逻辑,但注意:abort 后 promise 仍会 resolve/reject,需在 catch 中识别 abort 错误
示例:
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 8000);
<p>fetch('/api/long-task', { signal: controller.signal })
.then(res => { /<em> ... </em>/ })
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求已超时取消');
} else {
console.error('其他错误', err);
}
})
.finally(() => clearTimeout(timeoutId));</p>大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











