fetch 默认不校验HTTP状态码,404/500视为成功需手动检查res.ok;axios默认将4xx/5xx拒绝但需配置响应拦截器处理;两者上传FormData时均不可手动设置Content-Type头。

fetch 和 axios 都能发请求,但默认行为、错误处理、取消机制完全不同——别直接替换用,否则线上会丢 404 或超时失败不报错。
fetch 发请求时,404/500 不抛错,得手动检查 response.ok
这是最常踩的坑:fetch 只在网络异常(如断网、DNS 失败)时 reject,HTTP 状态码 404、500、401 全部算“成功”,then 里照样进。不检查就直接 res.json(),后面逻辑可能拿不到数据还静默失败。
- 必须加
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`) -
res.headers.get('content-type')要在res.clone()后才能多次读取,否则第二次调用返回 null - 没有内置 timeout,要靠
AbortController控制:const controller = new AbortController(); fetch(url, { signal: controller.signal }); setTimeout(() => controller.abort(), 8000);
axios 默认把 4xx/5xx 当错误,但响应拦截器里才能统一处理
axios 的 response 对象结构和原生不同,data 在 res.data,状态码在 res.status;它默认对非 2xx 状态码 reject,但这个 reject 会被 axios.interceptors.response.use 拦住——很多人没配拦截器,结果 catch 里拿到的是完整响应对象,不是错误实例。
- 全局配置超时:
axios.defaults.timeout = 10000,但单个请求可覆盖:axios.get('/api', { timeout: 5000 }) - 取消请求必须用
CancelToken(v0.22+ 已弃用)或AbortController(推荐):const controller = new AbortController(); axios.get('/api', { signal: controller.signal }); - 请求头自动带
Content-Type: application/json,但传FormData时得手动删掉:headers: { 'Content-Type': undefined }
上传文件时,fetch 要手动设 Content-Type: multipart/form-data?错,别设
如果用 FormData 构造请求体,fetch 和 axios 都**不能手动设置 Content-Type 头**——浏览器会自动生成带 boundary 的 multipart header,手动设会导致 boundary 缺失,后端解析失败(常见报错:Multipart: Boundary not found)。
动态WEB网站中的PHP和MySQL详细反映实际程序的需求,仔细地探讨外部数据的验证(例如信用卡卡号的格式)、用户登录以及如何使用模板建立网页的标准外观。动态WEB网站中的PHP和MySQL的内容不仅仅是这些。书中还提到如何串联JavaScript与PHP让用户操作时更快、更方便。还有正确处理用户输入错误的方法,让网站看起来更专业。另外还引入大量来自PEAR外挂函数库的强大功能,对常用的、强大的包
立即学习“Java免费学习笔记(深入)”;
- fetch 正确写法:
fetch('/upload', { method: 'POST', body: formData })(不加 headers) - axios 正确写法:
axios.post('/upload', formData, { headers: { 'Content-Type': undefined } }) - 进度监听:fetch 无原生支持,需用
XMLHttpRequest;axios 可用onUploadProgress: e => console.log(e.loaded / e.total)
真正难的不是怎么写那几行代码,而是记住哪些行为是“默认隐式发生”的:fetch 不校验 HTTP 状态、axios 自动序列化 JSON、两者对 FormData 的 header 处理逻辑相反……这些点在线上出问题时,日志里几乎不报错,只表现为你收不到数据。










