Ajax 原理

理解 Ajax 的工作机制和 XMLHttpRequest 的使用

问题

Ajax 是什么?它的工作原理是怎样的?

解答

Ajax(Asynchronous JavaScript and XML)是一种在不刷新页面的情况下与服务器交换数据的技术。

工作流程

  1. 创建 XMLHttpRequest 对象
  2. 配置请求(方法、URL、是否异步)
  3. 发送请求
  4. 监听状态变化,处理响应

基本实现

// 创建 XHR 对象
const xhr = new XMLHttpRequest();

// 配置请求:方法、URL、是否异步
xhr.open('GET', 'https://api.example.com/data', true);

// 监听状态变化
xhr.onreadystatechange = function () {
  // readyState 为 4 表示请求完成
  if (xhr.readyState === 4) {
    // status 为 200 表示成功
    if (xhr.status === 200) {
      console.log(JSON.parse(xhr.responseText));
    } else {
      console.error('请求失败:', xhr.status);
    }
  }
};

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

readyState 状态码

状态说明
0UNSENT对象已创建,未调用 open
1OPENEDopen 已调用
2HEADERS_RECEIVED收到响应头
3LOADING正在接收响应体
4DONE请求完成

封装 Ajax 函数

function ajax(options) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    const { method = 'GET', url, data, headers = {} } = options;

    // 配置请求
    xhr.open(method, url, true);

    // 设置请求头
    Object.keys(headers).forEach((key) => {
      xhr.setRequestHeader(key, headers[key]);
    });

    // 监听完成事件
    xhr.onload = function () {
      if (xhr.status >= 200 && xhr.status < 300) {
        resolve(JSON.parse(xhr.responseText));
      } else {
        reject(new Error(xhr.statusText));
      }
    };

    // 监听错误事件
    xhr.onerror = function () {
      reject(new Error('Network Error'));
    };

    // 发送请求
    xhr.send(data ? JSON.stringify(data) : null);
  });
}

// 使用示例
ajax({
  method: 'POST',
  url: '/api/users',
  headers: { 'Content-Type': 'application/json' },
  data: { name: 'Tom' },
})
  .then((res) => console.log(res))
  .catch((err) => console.error(err));

现代替代方案:Fetch API

// Fetch 是基于 Promise 的现代 API
fetch('/api/data')
  .then((response) => {
    if (!response.ok) {
      throw new Error('请求失败');
    }
    return response.json();
  })
  .then((data) => console.log(data))
  .catch((error) => console.error(error));

关键点

  • Ajax 通过 XMLHttpRequest 实现异步通信,页面无需刷新即可更新数据
  • readyState 有 5 个状态(0-4),4 表示请求完成
  • 需要同时检查 readyState 和 status 来判断请求是否成功
  • Fetch API 是现代浏览器提供的替代方案,基于 Promise,语法更简洁
  • XHR 支持监听上传进度(xhr.upload.onprogress),Fetch 原生不支持