AJAX 创建 XMLHttpRequest 对象(长文解析)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

在现代 Web 开发中,用户对网页的实时交互体验要求越来越高。传统的页面刷新方式不仅影响用户体验,还会增加服务器负担。AJAX(Asynchronous JavaScript and XML)技术的出现,完美解决了这一问题。它允许网页在不重新加载的情况下,与服务器进行数据交互,实现动态内容更新。而 AJAX 创建 XMLHttpRequest 对象正是这一技术的核心基础。本文将从零开始讲解如何通过 JavaScript 创建和使用 XMLHttpRequest 对象,并通过实际案例帮助读者掌握其应用场景与最佳实践。


一、什么是 AJAX?为什么需要它?

1.1 AJAX 的基本概念

AJAX 是一种结合了 JavaScript、XML(或 JSON)、CSS 等技术的组合方案。它的核心是 异步通信:通过 JavaScript 的 XMLHttpRequest 对象(或现代的 fetch API)向服务器发送请求,接收并处理响应数据,从而实现页面局部刷新。

形象比喻
假设你正在餐厅点餐,传统方式是每次点餐后必须等待服务员取走菜单并重新返回新菜单(页面刷新)。而 AJAX 则像服务员直接在你面前更新菜单内容,无需等待整张桌子的流程。

1.2 AJAX 的核心作用

  • 提升用户体验:页面无需频繁刷新,操作更流畅。
  • 减少服务器负载:仅传输必要的数据,而非整个页面。
  • 实现动态交互:如即时聊天、实时数据监控等场景。

二、XMLHttpRequest 对象详解

2.1 对象的创建与初始化

要使用 AJAX,首先需要创建 XMLHttpRequest 对象。该对象提供了与服务器通信的完整接口。

代码示例:创建对象

// 兼顾不同浏览器的兼容性写法
let xhr;
if (window.XMLHttpRequest) {
  xhr = new XMLHttpRequest(); // 现代浏览器
} else {
  xhr = new ActiveXObject("Microsoft.XMLHTTP"); // 旧版 IE
}

知识点解析

  • 跨浏览器兼容性:早期 IE 使用 ActiveXObject,而现代浏览器均支持原生 XMLHttpRequest
  • 对象实例化:通过 new XMLHttpRequest() 创建一个空的“通信通道”。

2.2 发送请求的核心方法

创建对象后,需要调用 open()send() 方法来执行请求。

代码示例:发送 GET 请求

// 1. 配置请求参数
xhr.open("GET", "https://api.example.com/data", true); // 第三个参数表示是否异步

// 2. 发送请求
xhr.send(); // GET 请求通常无需发送数据

参数说明

  • 方法类型:如 GET(获取数据)、POST(提交数据)。
  • URL:服务器端接口的路径。
  • 异步标志true 表示异步(默认),false 表示同步(不推荐,会阻塞页面)。

2.3 处理服务器响应

当服务器返回数据后,需要通过监听 XMLHttpRequest 的状态变化来获取结果。

代码示例:监听响应

// 监听 readyState 变化
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4 && xhr.status === 200) {
    // 请求成功,处理数据
    console.log(xhr.responseText); // 获取响应文本
  }
};

关键属性与状态码
| 属性/状态码 | 含义 |
|------------|------|
| readyState | 请求状态:0(未初始化)、1(加载中)、2(已加载)、3(交互中)、4(完成) |
| status | HTTP 状态码:200(成功)、404(未找到)、500(服务器错误) |


三、完整案例:实现动态数据加载

3.1 场景描述

假设我们需要在网页中动态加载用户列表,且不刷新页面。

HTML 结构

<div id="user-list"></div>
<button onclick="loadUsers()">加载用户数据</button>

JavaScript 实现

function loadUsers() {
  const xhr = new XMLHttpRequest();

  // 配置请求
  xhr.open("GET", "/api/users", true);

  // 监听响应
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        // 解析 JSON 数据并渲染到页面
        const users = JSON.parse(xhr.responseText);
        const userList = document.getElementById("user-list");
        users.forEach(user => {
          userList.innerHTML += `<div>${user.name} - ${user.email}</div>`;
        });
      } else {
        console.error("请求失败,状态码:" + xhr.status);
      }
    }
  };

  // 发送请求
  xhr.send();
}

运行流程

  1. 用户点击按钮,触发 loadUsers() 函数。
  2. 创建 XMLHttpRequest 对象并配置 GET 请求。
  3. 监听 onreadystatechange 事件,当状态为 4 且状态码为 200 时,解析返回的 JSON 数据并更新页面。

四、高级技巧与常见问题

4.1 发送 POST 请求与表单数据

POST 请求常用于提交数据,需通过 send() 方法传递参数。

代码示例:提交表单数据

// 配置 POST 请求
xhr.open("POST", "/api/submit", true);

// 设置请求头(必须显式声明 Content-Type)
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

// 构造参数
const params = "username=John&password=123456";

// 发送数据
xhr.send(params);

注意事项

  • 必须调用 setRequestHeader() 设置 Content-Type,否则服务器可能无法解析数据。
  • 复杂数据推荐使用 JSON 格式:
    const data = JSON.stringify({ username: "John", password: "123456" });
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(data);
    

4.2 跨域请求与 CORS

当请求的 URL 域名与当前页面不同,会触发 跨域限制。此时需服务器配置 CORS(跨域资源共享)。

服务器端响应头示例(Node.js):

res.header("Access-Control-Allow-Origin", "*"); // 允许所有域名
res.header("Access-Control-Allow-Methods", "GET, POST");

替代方案

  • JSONP:仅支持 GET 请求,通过动态创建 <script> 标签绕过限制。
  • 代理服务器:在同源服务器上搭建代理,转发请求。

4.3 错误处理与超时控制

代码示例:超时控制

xhr.timeout = 5000; // 设置超时时间为 5 秒

// 监听超时事件
xhr.ontimeout = function() {
  console.error("请求超时!");
};

// 监听错误事件
xhr.onerror = function() {
  console.error("请求失败,请检查网络!");
};

五、与现代 API 的对比:XMLHttpRequest vs Fetch

尽管 XMLHttpRequest 是 AJAX 的基石,但现代开发更倾向使用 fetch() API。

对比表格

特性XMLHttpRequestFetch API
异步性需手动设置默认异步
链式调用不支持支持 .then() 链式
流式处理无内置支持支持响应流
代码简洁性较复杂更简洁

示例代码

// 使用 Fetch 实现相同功能
fetch("/api/users")
  .then(response => response.json())
  .then(data => {
    // 处理数据
  })
  .catch(error => console.error("请求失败:", error));

六、总结与实践建议

6.1 核心知识点回顾

  1. 创建对象:通过 new XMLHttpRequest() 初始化通信通道。
  2. 发送请求:使用 open()send() 方法配置并执行请求。
  3. 处理响应:监听 readyStatestatus 确认请求结果。
  4. 错误处理:通过超时、错误监听提升健壮性。

6.2 学习路径建议

  • 初学者:从 GET 请求开始,逐步尝试 POST、JSON 数据处理。
  • 中级开发者:结合实际项目,探索 Fetch API、CORS、数据校验等进阶内容。

6.3 实践案例推荐

  • 实现一个 实时搜索功能:输入关键词时,动态加载匹配结果。
  • 构建 待办事项列表:通过 AJAX 提交和删除任务,无需刷新页面。

结论

通过本文,我们系统学习了 AJAX 创建 XMLHttpRequest 对象的全流程,并通过案例掌握了其核心用法。这一技术不仅是 Web 开发的基石,更是构建现代化单页应用(SPA)的关键技能。建议读者通过实际编码加深理解,并尝试将所学应用于真实项目中。记住,实践是掌握技术的最佳途径!

“代码的真正用途是让人类理解,而让计算机执行只是附带品。” —— 《代码大全》

最新发布