fetch() 更适合现代项目因其设计更简洁、基于 Promise 且与 Service Worker 兼容,但需手动处理 cookie、HTTP 错误和 JSON 解析;兼容性差(IE 不支持),建议用 axios 或封装回退;数据校验、加载状态管理、DOM 渲染优化和用户路径完整性是关键实践。

为什么 fetch() 比 XMLHttpRequest 更适合现代项目
默认不带 cookie、不自动解析 JSON、错误状态码(如 404/500)不会 reject——这些不是 bug,是设计选择。用 fetch() 必须手动检查 response.ok 和调用 response.json(),否则静默失败很常见。
实操建议:
- 始终用
if (!response.ok) throw new Error(response.status)拦截 HTTP 错误 - 不要省略
await response.json(),fetch()返回的是 ReadableStream,不是数据本身 - 需要携带 cookie 时,必须显式传
{ credentials: 'include' },默认是'omit' - IE 完全不支持,若需兼容,直接上
axios或封装一层XMLHttpRequest回退逻辑
渲染前必须校验数据结构,而不是假设后端永远返回正确格式
后端字段缺失、类型错位(比如 id 是字符串却当数字用)、嵌套层级变更——这些在联调期未必暴露,上线后极易导致 Cannot read property 'xxx' of undefined。
实操建议:
- 用可选链操作符快速防御:
data?.items?.[0]?.title,但别依赖它掩盖深层问题 - 对关键字段做存在性断言:
if (!Array.isArray(data.list)) { console.error('expected array, got', typeof data.list); return; } - 复杂结构建议配合 TypeScript 类型守卫或
zod做运行时校验,尤其在 SSR 或缓存场景下 - 模板渲染时避免直接插值
${data.user.name},先确保data.user存在,否则用空对象兜底
加载状态、错误提示和空状态不能靠“等接口返回再决定”
用户点击按钮后,界面卡住 2 秒没反馈,大概率会重复点击;列表为空时只留白,用户不知道是没数据、加载失败还是网络中断。
实操建议:
- 发起请求前立即置
loading = true,而非等fetch开始执行——微任务队列延迟可能导致视觉滞后 - 错误处理要区分类型:网络错误(
TypeError: failed to fetch)、HTTP 错误(401、503)、业务错误({ code: 1001, msg: '库存不足' }),各自对应不同 UI 提示 - 空状态文案需具体:
暂无订单比暂无数据更明确;如果是搜索结果为空,应提供重试按钮或引导词 - 防抖或节流仅适用于频繁触发场景(如搜索框输入),普通列表加载不用加,反而掩盖真实加载意图
DOM 渲染性能容易被忽略的三个点
数据量不大时看不出问题,但一旦列表项超 100 条,直接拼接字符串 + innerHTML 或频繁 appendChild 就会明显卡顿。
实操建议:
真实项目里最常出问题的,不是请求发不出去,而是数据到了、结构对了、也渲染了,但用户操作路径断裂——比如加载中禁用了按钮却忘了恢复,或者错误态清除了 loading 状态但没重置表单。这些细节比技术选型更影响体验。










