从XMLHttpRequest到Fetch:前后端通信的"进化史"

在前端开发的世界里,有这样一位"信使",它让网页告别了刷新就能获取新数据的时代,它让SPA(单页应用)成为可能,它就是------AJAX(Asynchronous JavaScript and XML)。今天,咱们就来聊聊这位"信使"的成长史,从"老派"的XMLHttpRequest到"现代"的Fetch API。

一、XMLHttpRequest:AJAX的"老黄牛"

要说AJAX界的"老资历",非XMLHttpRequest莫属。这位老兄虽然名字里带着"XML",但现在它可是能处理各种数据格式,一点都不"偏科"。

咱们先来看一段经典的XMLHttpRequest使用代码:

javascript 复制代码
function getData() {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();  // 创建异步对象
    xhr.open('GET', 'https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer', true); // 准备请求
    xhr.send(); // 发送请求
    // 监测请求状态
    xhr.onreadystatechange = function () {
      if (xhr.readyState == 4 && xhr.status == 200) { // 请求成功
        let data = JSON.parse(xhr.responseText); // 解析数据
        resolve(data.data);
      }
    }
  })
}

这段代码完美诠释了使用XMLHttpRequest的"四步曲":

  1. 创建对象new XMLHttpRequest() - 就像制作了一个"信使"机器人
  2. 准备请求xhr.open(method, url, async) - 告诉"信使"要去哪儿、做什么
  3. 发送请求xhr.send() - 拍拍"信使"的肩膀:"出发吧!"
  4. 监听响应xhr.onreadystatechange - 守在门口等"信使"带回消息

这里有个小知识点:readyState是个状态码,从0到4,分别代表"未初始化"、"已打开"、"已发送"、"已接收部分数据"、"请求完成"。只有当它变成4,并且status是200的时候,才说明"信使"圆满完成了任务。

二、Fetch API:AJAX界的"小鲜肉"

随着JavaScript的发展,一位名叫Fetch API的"小鲜肉"横空出世。它基于Promise,使用链式调用,代码更加简洁优雅,很快就赢得了前端开发者的喜爱。

咱们来看看Fetch API是怎么发送请求的:

javascript 复制代码
fetch('https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer?page=1', {
  method: 'GET'
}).then((response) => {
  return response.json(); // 解析JSON数据
}).then((data) => {
  console.log(data); // 处理数据
}).catch((error) => {
  console.error('请求失败:', error); // 捕获错误
});

是不是感觉代码清爽了很多?Fetch API有几个明显的优势:

  1. 基于Promise:告别了回调地狱,代码更加扁平化
  2. API设计更现代:使用了ES6+的语法特性,符合现代JavaScript的编程风格
  3. 功能更强大:支持流式处理、跨域处理等高级特性

但Fetch API也有一些"小脾气"需要注意:

  • 默认不会发送cookie,需要手动设置credentials: 'include'
  • 不会自动拒绝HTTP错误状态码(如404、500),需要手动检查response.ok
  • 不支持超时设置,需要自己封装

三、实战对比:两位"信使"的PK

为了更直观地感受两位"信使"的差异,咱们来做个小实验。假设我们要获取歌手列表并显示在页面上,看看它们是怎么工作的。

使用XMLHttpRequest的版本:

javascript 复制代码
// 点击按钮获取数据
btn.addEventListener('click', () => {
  // 获取歌手数据
  getData().then((data) => {
    renderList(data); // 渲染列表
  })
});

function getData() {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', 'https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer', true);
    xhr.send();
    xhr.onreadystatechange = function () {
      if (xhr.readyState == 4 && xhr.status == 200) {
        let data = JSON.parse(xhr.responseText);
        resolve(data.data);
      }
    }
  })
}

function renderList(arr) {
  let list = document.getElementById('list');
  for (let i = 0; i < arr.length; i++) {
    let item = arr[i];
    let li = document.createElement('li');
    li.innerText = `${item.name} -- ${item.songsCount}`;
    list.appendChild(li);
  }
}

使用Fetch API的版本:

javascript 复制代码
btn.addEventListener('click', () => {
  fetch('https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer?page=1')
    .then(response => response.json())
    .then(data => {
      renderList(data.data); // 渲染列表
    })
    .catch(error => console.error('获取数据失败:', error));
});

// renderList函数与上面相同

通过对比,我们可以看到Fetch API的代码更加简洁明了,链式调用让逻辑更加清晰。但XMLHttpRequest作为"老黄牛",兼容性更好,在一些旧浏览器上也能正常工作。

四、如何选择:没有最好,只有最适合

既然两位"信使"各有千秋,那我们在实际开发中该如何选择呢?这里给大家几个小建议:

  1. 如果项目需要兼容IE浏览器:老老实实用XMLHttpRequest吧,它的兼容性没话说
  2. 如果是现代项目,且使用了Promise或async/await:果断选择Fetch API,它的语法更现代,代码更优雅
  3. 如果需要处理复杂的请求场景:可以考虑使用Axios等第三方库,它们基于XMLHttpRequest封装,提供了更多便捷的功能

写在最后

从XMLHttpRequest到Fetch API,AJAX技术的发展见证了前端开发的进步。无论是"老黄牛"还是"小鲜肉",它们的存在都是为了让前后端通信更加高效、便捷。

作为前端开发者,我们不需要纠结于哪个技术更"高级",而是要根据实际需求选择最合适的工具。毕竟,能解决问题的技术,就是好技术!

希望这篇文章能让你对AJAX技术有更深入的了解。如果你有任何疑问,或者有更好的使用技巧,欢迎在评论区留言讨论!

小贴士:在实际开发中,为了处理Fetch API的一些"小脾气",我们可以封装一个通用的请求函数,添加超时处理、错误处理等功能,让API调用更加健壮哦!

相关推荐
Double__King2 分钟前
巧用 CSS 伪元素,让背景图自适应保持比例
前端
Mapmost3 分钟前
【BIM+GIS】BIM数据格式解析&与数字孪生适配的关键挑战
前端·vue.js·three.js
一涯4 分钟前
写一个Chrome插件
前端·chrome
鹧鸪yy11 分钟前
认识Node.js及其与 Nginx 前端项目区别
前端·nginx·node.js
跟橙姐学代码12 分钟前
学Python必须迈过的一道坎:类和对象到底是什么鬼?
前端·python
汪子熙14 分钟前
浏览器里出现 .angular/cache/19.2.6/abap_test/vite/deps 路径究竟说明了什么
前端·javascript·面试
Benzenene!16 分钟前
让Chrome信任自签名证书
前端·chrome
yangholmes888816 分钟前
如何在 web 应用中使用 GDAL (二)
前端·webassembly
jacy18 分钟前
图片大图预览就该这样做
前端