从 Ajax 到 Fetch:前端请求方式的演进到底带来了什么
前端开发离不开请求。
页面展示数据、提交表单、刷新列表、加载详情,这些动作几乎都要和服务端通信。
如果把时间往前拉,大家最熟悉的方式可能是 Ajax;再往后,Fetch 逐渐成为更常见的写法。它们都能完成请求,但带来的开发体验并不完全一样。
Ajax 解决了什么问题
Ajax 最重要的价值,是让页面不必整页刷新也能和服务端交换数据。
这在早期前端开发里是一次很大的改变,因为它让页面开始具备更强的交互性和动态性。
大家最熟悉的实现通常是 XMLHttpRequest。
1const xhr = new XMLHttpRequest(); 2xhr.open('GET', '/api/list'); 3xhr.onreadystatechange = function () { 4 if (xhr.readyState === 4 && xhr.status === 200) { 5 console.log(xhr.responseText); 6 } 7}; 8xhr.send();
这个写法并不是不能用,但确实比较底层。
Fetch 为什么更容易被接受
Fetch 更贴近现代 JavaScript 的编码方式。
它的 API 更简洁,也更容易和 Promise、async/await 组合。
1async function loadData() { 2 const response = await fetch('/api/list'); 3 const data = await response.json(); 4 console.log(data); 5}
相比 XMLHttpRequest,这种写法的优势主要体现在:
- 更容易阅读
- 更容易封装
- 更适合现代异步流程
两者的差异不只是“新旧”
不少人会简单理解成“Fetch 就是更现代的 Ajax”,但更准确地说,它们代表了两种不同层级的开发体验。
XMLHttpRequest 更像底层接口,你需要自己处理很多状态变化。
Fetch 则更像一个围绕请求流程设计得更现代的抽象。
Fetch 使用时也有需要注意的地方
虽然 Fetch 更简洁,但它也有一些容易踩坑的点。
例如很多人第一次用时会以为:
- 请求失败就会进入
catch
实际上不是所有 HTTP 错误状态都会自动抛异常。比如返回 404、500,Fetch 依然可能算“成功收到响应”,只是 response.ok 为 false。
所以通常还要自己判断:
1const response = await fetch('/api/list'); 2 3if (!response.ok) { 4 throw new Error('request failed'); 5}
请求封装的重要性
无论使用 Ajax 还是 Fetch,真正影响项目维护体验的,往往不是底层 API 本身,而是你有没有做好请求层封装。
例如:
- base URL
- 通用 headers
- 错误处理
- token 注入
- 超时控制
如果这些都散落在页面里,请求方式再现代,项目后期也会很难维护。
从工具切换到抽象思维
很多技术演进表面看起来只是 API 更新,实际上还有一个更关键的问题是推动开发者思维变化。
从 Ajax 到 Fetch,更有价值的变化不只是代码少了几行,而是前端异步请求开始更自然地融入整体工程结构。
写在最后
从 Ajax 到 Fetch,是前端请求方式一次很自然的演进。前者解决了页面局部更新的问题,后者则让请求代码更容易和现代 JavaScript 编程方式结合。
工具当然会变化,但真正值得沉淀的是请求层的组织方式。只要这层思路清楚,用什么接口都不会太乱。