AJAX 详解:概念、原理与实现方法

一、基本概念

AJAX(Asynchronous JavaScript and XML)即异步 JavaScript 和 XML,是一种无需重新加载整个网页 就能向服务器请求数据并更新部分页面的技术。它的核心是异步 ------ 在后台与服务器交换数据时,用户仍可与页面交互,大幅提升了 Web 应用的响应速度和用户体验。

尽管名字包含 XML,但现代 AJAX 更多使用 JSON 格式传输数据,因为 JSON 更轻量、解析更快。

二、工作原理

AJAX 的工作流程基于客户端 - 服务器模型,通过中间层(XMLHttpRequest 对象或 Fetch API)实现异步通信:

  1. 用户触发事件(如点击按钮、页面加载)
  2. JavaScript 创建请求对象(XMLHttpRequest 或使用 Fetch)
  3. 请求对象向服务器发送请求(GET/POST 等)
  4. 服务器处理请求并返回数据(JSON/XML/ 文本等)
  5. 请求对象接收数据并通知 JavaScript
  6. JavaScript 更新页面 DOM(只更新需要变化的部分)

整个过程无需刷新页面,实现了页面的局部更新。

三、实现方法

1. XMLHttpRequest

XMLHttpRequest(XHR)是最早出现的用于在浏览器端与服务器进行异步通信的技术,也是 AJAX(Asynchronous JavaScript and XML)的核心。

基本使用示例

  • 触发点击事件,执行回调函数, 调用 getData() 发送请求获取数据
  • 在 Promise 的执行器函数中,创建了 XMLHttpRequest 对象并发送请求
  • 通过监听 onreadystatechange 事件处理请求状态变化
  • 获得响应的数据并渲染在页面

向网页(GET /mock/66585c4db462b81cb3916d3e/songer/songer)发送请求获得响应的数据并更新在页面中

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <button id="btn">获取歌手信息</button>
  <div id="app">
    <ul id="list"></ul>
  </div>

  <script>
    let btn = document.getElementById('btn')
    let rowData = []

    btn.addEventListener('click', () => {
      // 获取歌手数据
      getData().then(() => {
        renderList(rowData)
      })
    })

    function getData() {
      return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()  // 创建异步对象
        console.log(xhr);
        xhr.open('GET', 'https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer', true) // 准备请求的参数
        xhr.send() // 发送请求
        // 监测请求的发送结果
        xhr.onreadystatechange = function () {
          console.log(xhr);
          if (xhr.readyState == 4 && xhr.status == 200) { // 请求成功
            // 处理数据
            let data = JSON.parse(xhr.responseText) // 把 json 字符串转换为json 对象
            console.log(data.data);
            rowData = data.data
            resolve()
            // renderList(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)
      }
    }

  </script>
</body>

</html>

关键步骤解析

js 复制代码
const xhr = new XMLHttpRequest()  // 创建异步对象
  • 创建 XMLHttpRequest 实例,这是发起 AJAX 请求的基础
javascript 复制代码
    xhr.open('GET', 'https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer', true)
  • open() 方法初始化请求

    • 第一个参数:请求方法(GET)

    • 第二个参数:请求 URL(一个模拟接口)

    • 第三个参数:true 表示异步请求(这是 AJAX 的核心特性)

javascript 复制代码
    xhr.send() // 发送请求
  • 发送请求到服务器,对于 GET 请求不需要传递参数
javascript 复制代码
    xhr.onreadystatechange = function () { ... }
  • 注册状态变化事件处理函数,当请求状态(readyState)发生变化时触发
javascript 复制代码
    if (xhr.readyState == 4 && xhr.status == 200) { ... }
  • 检查请求是否完成(readyState == 4)且响应成功(status == 200

    • 只有同时满足这两个条件,才认为请求成功
javascript 复制代码
    let data = JSON.parse(xhr.responseText)
  • 将服务器返回的 JSON 字符串解析为 JavaScript 对象
javascript 复制代码
    rowData = data.data  // 假设 rowData 是外部定义的变量
    resolve()  // 通知 Promise 成功完成
  • 存储数据到外部变量 rowData
  • 调用 resolve() 标记 Promise 为成功状态

2. Fetch API

Fetch API 是 ES6 引入的新一代网络请求 API,基于 Promise 设计,语法更简洁,功能更强大。

特点

  • 基于 Promise,支持 async/await 语法,代码结构更清晰,避免了回调地狱。
  • 默认不携带 Cookie,需要手动设置 credentials: 'include'
  • 只有网络错误(如断网)才会触发 Promise 的 reject,HTTP 错误状态码(如 404、500)不会导致 reject,需要手动处理。
  • 支持流式处理响应体,可以分块读取大型响应。 基本使用示例
js 复制代码
function getData() {
      // 使用Fetch API替代XMLHttpRequest
      return fetch('https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer', {
        method: 'GET', // 请求方法
        headers: {
          'Content-Type': 'application/json'
        }
      })
      .then(response => {
        // 检查HTTP响应状态
        if (!response.ok) {
          throw new Error(`HTTP错误,状态码: ${response.status}`)
        }
        // 解析JSON响应
        return response.json()
      })
      .then(data => {
        // 返回需要的数据部分
        rowData = data.data
        return data.data
      })
    }

关键步骤解析

1. 发起请求
javascript 复制代码
return fetch('https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer', {
  method: 'GET', // 请求方法
  headers: {
    'Content-Type': 'application/json'
  }
})
  • fetch() 是 Fetch API 的核心方法,用于发起网络请求,返回一个 Promise 对象 (这也是可以链式调用 .then() 的原因)。

  • 第一个参数:请求的 URL(这里是一个模拟歌手数据的接口)。

  • 第二个参数(配置对象):

    • method: 'GET':指定请求方法为 GET(默认就是 GET,可省略)。
    • headers:设置请求头,这里声明请求的数据类型为 JSON。
2. 处理响应状态
javascript 复制代码
    .then(response => {
      // 检查HTTP响应状态
      if (!response.ok) {
        throw new Error(`HTTP错误,状态码: ${response.status}`)
      }
      // 解析JSON响应
      return response.json()
    })
  • 第一个 .then() 接收 fetch 返回的 Response 对象(代表服务器响应)。
  • response.ok:是 Response 对象的属性,当 HTTP 状态码为 2xx 范围 (如 200、201)时为 true,否则为 false
  • 如果响应状态错误(如 404、500),通过 throw 主动抛出错误,会被后续的 .catch() 捕获。
  • response.json():将服务器返回的 JSON 字符串解析为 JavaScript 对象,返回一个新的 Promise ,因此可以继续链式调用 .then()
3. 提取有效数据
javascript 复制代码
    .then(data => {
      // 返回需要的数据部分
      rowData = data.data
      return data.data
    })
  • 第二个 .then() 接收上一步解析后的 JSON 数据(即服务器返回的完整响应体)。
  • 假设接口返回的数据结构是 { data: [...] }(通常接口会将核心数据放在 data 字段中),这里提取 data.data 作为有效数据。
  • rowData = data.data:将数据存储到全局变量 rowData(便于其他地方使用)。
  • return data.data:将有效数据返回,使得调用 getData() 时可以通过 .then(data => { ... }) 获取该数据。

3. axios

axios 是一个基于 Promise 的 HTTP 客户端,可以在浏览器和 Node.js 环境中使用,本质上是对 XMLHttpRequest 的封装,同时也支持一些更高级的特性。

特点

  • 基于 Promise,支持 async/await 语法。
  • 自动转换 JSON 数据,无需手动解析。
  • 默认携带 Cookie,可通过 withCredentials 配置。
  • 拦截请求和响应,方便在请求发送前或响应返回后进行统一处理(如添加请求头、处理错误等)。
  • 支持取消请求。
  • 提供了请求超时处理。

基本使用示例

html 复制代码
<!-- 引入axios库 -->
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
js 复制代码
function getData() {
      // 使用axios发送GET请求
      return axios.get('https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer', {
        headers: {
          'Content-Type': 'application/json'
        },
        timeout: 5000 // 设置超时时间为5秒
      })
      .then(response => {
        // axios会自动解析JSON数据,响应数据在response.data中
        rowData = response.data.data
        return rowData
      })
    }
相关推荐
刚入坑的新人编程2 分钟前
暑期算法训练.9
数据结构·c++·算法·leetcode·面试·排序算法
陈随易8 分钟前
AI新技术VideoTutor,幼儿园操作难度,一句话生成讲解视频
前端·后端·程序员
Pedantic11 分钟前
SwiftUI 按钮Button:完整教程
前端
前端拿破轮13 分钟前
2025年了,你还不知道怎么在vscode中直接调试TypeScript文件?
前端·typescript·visual studio code
代码的余温16 分钟前
DOM元素添加技巧全解析
前端
JSON_L18 分钟前
Vue 电影导航组件
前端·javascript·vue.js
用户214118326360226 分钟前
01-开源版COZE-字节 Coze Studio 重磅开源!保姆级本地安装教程,手把手带你体验
前端
大模型真好玩40 分钟前
深入浅出LangChain AI Agent智能体开发教程(四)—LangChain记忆存储与多轮对话机器人搭建
前端·人工智能·python
帅夫帅夫1 小时前
深入理解 JWT:结构、原理与安全隐患全解析
前端
Struggler2811 小时前
google插件开发:如何开启特定标签页的sidePanel
前端