从 Ajax 到 Fetch:前端请求方式的演进到底带来了什么

0 阅读

前端开发离不开请求。

页面展示数据、提交表单、刷新列表、加载详情,这些动作几乎都要和服务端通信。

如果把时间往前拉,大家最熟悉的方式可能是 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.okfalse

所以通常还要自己判断:

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 编程方式结合。

工具当然会变化,但真正值得沉淀的是请求层的组织方式。只要这层思路清楚,用什么接口都不会太乱。