onreadystatechange 事件

XMLHttpRequest 的状态变化事件及 readyState 各阶段含义

问题

解释 XMLHttpRequest 的 onreadystatechange 事件,以及 readyState 的各个状态值。

解答

onreadystatechange 是 XMLHttpRequest 对象的事件处理器,当 readyState 属性发生变化时触发。

readyState 的 5 个状态

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

基本用法

const xhr = new XMLHttpRequest();

xhr.onreadystatechange = function() {
  console.log('readyState:', xhr.readyState);
  
  // 请求完成且成功
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log('响应数据:', xhr.responseText);
  }
};

xhr.open('GET', 'https://api.example.com/data');
xhr.send();

完整示例:封装 AJAX 请求

function ajax(options) {
  const { method = 'GET', url, data = null, success, error } = options;
  
  const xhr = new XMLHttpRequest();
  
  xhr.onreadystatechange = function() {
    // 只在请求完成时处理
    if (xhr.readyState !== 4) return;
    
    if (xhr.status >= 200 && xhr.status < 300) {
      // 尝试解析 JSON
      try {
        const response = JSON.parse(xhr.responseText);
        success && success(response);
      } catch (e) {
        success && success(xhr.responseText);
      }
    } else {
      error && error(xhr.status, xhr.statusText);
    }
  };
  
  xhr.open(method, url);
  
  // POST 请求设置请求头
  if (method.toUpperCase() === 'POST') {
    xhr.setRequestHeader('Content-Type', 'application/json');
  }
  
  xhr.send(data ? JSON.stringify(data) : null);
  
  return xhr;
}

// 使用示例
ajax({
  method: 'GET',
  url: '/api/users',
  success(data) {
    console.log('成功:', data);
  },
  error(status, statusText) {
    console.log('失败:', status, statusText);
  }
});

与 onload 的区别

const xhr = new XMLHttpRequest();

// onreadystatechange: 状态每次变化都触发(0→1→2→3→4)
xhr.onreadystatechange = function() {
  console.log('状态变化:', xhr.readyState);
};

// onload: 只在请求成功完成时触发一次
xhr.onload = function() {
  console.log('请求完成');
};

// onerror: 网络错误时触发
xhr.onerror = function() {
  console.log('网络错误');
};

xhr.open('GET', '/api/data');
xhr.send();

关键点

  • readyState 有 5 个值(0-4),4 表示请求完成
  • onreadystatechange 在每次状态变化时都会触发
  • 判断成功需要同时检查 readyState === 4status === 200
  • 现代开发更推荐使用 onload 事件或 fetch API
  • onreadystatechange 是理解 AJAX 原理的基础