fetch需手动处理HTTP错误、URL参数用URLSearchParams编码、POST需设Content-Type并JSON.stringify、取消请求用AbortController。

JavaScript 发送网络请求,fetch 是当前标准做法,但直接用它容易掉进缓存、错误不抛异常、JSON 解析失败等坑里。
fetch 不会自动抛出网络错误,404/500 也会进 then
这是最常被忽略的一点:fetch 只有在网络完全断开、DNS 失败、请求被阻止(如 CORS)时才 reject;HTTP 状态码如 404、500 仍会走 then 分支。
- 必须手动检查
response.ok(即status >= 200 && status ) - 或者显式判断
response.status - 否则后端返回错误 JSON 或空响应体,
response.json()会因解析失败而 reject,和 HTTP 错误混在一起难定位
fetch('/api/user')
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.catch(err => console.error('请求失败:', err));
GET 请求带参数,别手拼 URL 字符串
手动拼接 ?key=value&key2=value2 容易漏编码,尤其含中文、空格、特殊符号时会出错。
- 用
URLSearchParams生成查询字符串,自动编码 - 再拼到 URL 后面,比
encodeURIComponent手动包每个值更安全 - 注意:IE 不支持
URLSearchParams,需 polyfill 或改用new URL()(兼容性稍好)
const params = new URLSearchParams({ name: '张三', tag: '前端' });
fetch(`/api/search?${params}`); // 自动变成 /api/search?name=%E5%BC%A0%E4%B8%89&tag=%E5%89%8D%E7%AB%AF
POST 提交 JSON 数据,记得设 Content-Type 和 body
fetch 默认不发任何 body,也不设 Content-Type,后端可能收不到或解析失败。
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
立即学习“Java免费学习笔记(深入)”;
-
body必须是字符串(JSON.stringify(data)),不能传对象 -
headers中要显式加'Content-Type': 'application/json' - 如果后端要求
application/x-www-form-urlencoded,就用URLSearchParams构造body,而非 JSON
fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'admin', password: '123' })
});
需要取消请求?AbortController 是唯一标准方案
原生 fetch 没有类似 axios.cancel() 的快捷方法,必须靠 AbortController。
- 创建
controller = new AbortController(),把controller.signal传给fetch - 调用
controller.abort()即可中止请求(触发AbortError) - 注意:已响应完成的请求无法取消;仅对传输中请求有效
- React/Vue 中组件卸载时忘记 abort,可能引发“更新已卸载组件”警告
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal })
.catch(err => {
if (err.name === 'AbortError') console.log('请求已被取消');
});
// 后续某处
controller.abort();
真正麻烦的不是怎么发请求,而是处理边界:超时没配、错误状态没判、JSON 解析前没检查 res.headers.get('content-type') 是否含 json、取消逻辑没清理干净。这些地方一漏,问题就藏得深。









