JavaScript AJAX

一、AJAX 核心基础:异步交互的基石

1. 同步与异步:交互模式的本质差异

AJAX 的核心是 “异步”,需先明确两种交互模式的区别:

类型 执行逻辑 特点 生活案例 前端场景举例
同步 任务按顺序执行,前一个完成后才执行下一个 阻塞后续任务,效率低 打电话时,需挂断当前通话才能接新电话 表单提交刷新页面、alert 弹窗
异步 任务并行执行,无需等待前一个任务结果 非阻塞,效率高,需回调 同时接收多条短信,无需等待一条处理完 AJAX 请求、定时器 setTimeout
关键结论:
  • 同步:“排队执行”,必须等待结果;异步:“并行执行”,通过回调函数获取结果。
  • AJAX 的核心价值:无刷新页面局部更新,即不重新加载整个页面,仅更新需要的数据区域(如注册时实时验证手机号是否已存在)。

2. AJAX 定义与技术栈

  • 全称:Asynchronous JavaScript And XML(异步 JavaScript 和 XML)。
  • 本质:不是编程语言,而是一套 “创建交互式网页” 的技术组合,核心是 “用 JS 异步请求数据并更新 DOM”。
  • 技术栈构成
    • 前端:JavaScript(逻辑控制)、HTML/CSS(页面展示)、DOM(局部更新)。
    • 数据传输:XMLHttpRequest(核心对象,发送异步请求)。
    • 数据格式:早期用 XML,现在主流用 JSON(轻量、易解析)。

3. 前后端交互的 3 种核心方式

AJAX 是现代前端的主流交互方式,需与传统方式区分:

交互方式 实现方式 特点 适用场景
Form 表单提交 通过 <form> 标签的 action 和 method 同步,刷新整个页面 简单登录、注册(无实时验证需求)
标签自动请求 通过 <a href><img src> 等标签 同步加载资源,无需 JS 加载图片、跳转页面、引入脚本
AJAX 通过 XMLHttpRequest 对象发送请求 异步,无刷新局部更新 实时验证、列表分页、数据搜索

二、AJAX 工作原理与实现步骤(原生 JS)

AJAX 的执行流程可概括为 “四步走”:创建请求对象 → 配置请求 → 发送请求 → 处理响应

1. 完整实现步骤(兼容 IE 5/6)

步骤 1:创建 XMLHttpRequest 对象(请求载体)
// 现代浏览器(Chrome/Firefox/Edge)
if (window.XMLHttpRequest) {
  var xhr = new XMLHttpRequest();
} 
// IE 5/6 兼容(旧浏览器)
else if (window.ActiveXObject) {
  var xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
步骤 2:配置请求信息(open 方法)
// 语法:xhr.open(请求方法, 请求地址, 是否异步)
// 1. GET 请求:参数拼接在 URL 后(需用 encodeURI***ponent 处理特殊字符)
var params = "username=" + encodeURI***ponent("张三") + "&age=18";
xhr.open("GET", "test.php?" + params, true); // true = 异步,false = 同步

// 2. POST 请求:参数在 send 中传递,需设置请求头
xhr.open("POST", "test.php", true);
// 必须设置 Content-Type,告诉服务器参数格式(仅 POST 需设置)
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
步骤 3:发送请求(send 方法)
// GET 请求:send 传 null 或空
xhr.send(null);

// POST 请求:send 中传递参数(格式与 URL 参数一致)
xhr.send("username=张三&age=18");
步骤 4:监听响应(onreadystatechange 事件)

通过 readyState(请求状态)和 status(HTTP 状态码)判断请求是否成功:

xhr.onreadystatechange = function () {
  // readyState === 4:请求已完成,响应已就绪
  // status === 200:HTTP 请求成功(404=资源未找到,500=服务器错误)
  if (xhr.readyState === 4 && xhr.status === 200) {
    // 服务器返回的数据:responseText(文本)、responseXML(XML)
    var responseData = xhr.responseText;
    // 处理数据(如更新 DOM)
    document.getElementById("result").innerText = responseData;
  }
};
核心属性解析:
属性 含义 关键取值说明
readyState XMLHttpRequest 请求状态 0(未初始化)→ 4(已完成)
status HTTP 响应状态码 200(成功)、404(未找到)、500(错误)
responseText 服务器返回的文本数据 常用(如 JSON 字符串)
onreadystatechange 状态变化时的回调函数 每次 readyState 变化都会触发

2. AJAX 优缺点

优点:
  1. 无刷新更新:局部更新页面,减少用户等待,提升体验(如实时搜索提示)。
  2. 减轻服务器负担:仅请求所需数据,而非整个页面(如分页仅加载当前页数据)。
  3. 数据与显示分离:前端负责展示,后端负责数据,便于团队协作维护。
  4. 跨平台兼容:基于标准 Web 技术,支持所有现代浏览器。
缺点:
  1. SEO 不友好:数据通过 JS 动态加载,搜索引擎难以抓取(需用 SSR 等技术优化)。
  2. 破坏浏览器历史:无刷新交互不生成历史记录,Back 按钮无效(需用 history.pushState 解决)。
  3. 跨域限制:浏览器 “同源策略” 禁止 AJAX 请求非同源域名(需 CORS、JSONP 等方案解决)。
  4. 编码限制:默认仅支持 UTF-8 编码数据,需统一前后端编码格式。

三、后端支撑:PHP 与 JSON-Server

AJAX 需要后端接口返回数据,以下介绍两种常用后端方案:PHP(真实后端) 和 JSON-Server(模拟后端)

1. PHP 基础:搭建真实后端接口

1.1 PHP 环境搭建(XAMPP/PHPStudy)
  • 工具选择:XAMPP(集成 Apache 服务器、MySQL、PHP)或 PHPStudy(中文界面,更易操作)。
  • 核心步骤
    1. 下载安装:XAMPP 官网(https://www.apachefriends.org/),PHPStudy 官网(https://www.xp.***/)。
    2. 启动服务:启动 Apache(处理 HTTP 请求)和 MySQL(可选,用于数据库)。
    3. 项目目录:XAMPP 为 xampp/htdocs,PHPStudy 为 phpstudy_pro/WWW(PHP 文件需放在此目录)。
    4. 访问测试:浏览器输入 http://127.0.0.1,可查看项目目录列表。
1.2 PHP 核心语法(与 AJAX 交互相关)
(1)变量定义与输出
  • 变量以 $ 开头,弱类型语言,无需声明类型。
  • 输出函数:echo(常用,输出字符串)、print_r(输出数组)、var_dump(输出变量类型 + 值)。

php

// 变量定义
$username = "张三";
$age = 18;
$hobby = array("篮球", "编程");

// 输出(给 AJAX 返回数据)
echo $username; // 输出:张三
print_r($hobby); // 输出:Array ( [0] => 篮球 [1] => 编程 )
var_dump($age); // 输出:int(18)
(2)接收 AJAX 参数(GET/POST)

PHP 通过超全局数组接收 AJAX 传递的参数:

  • $_GET:接收 GET 方式参数(URL 拼接)。
  • $_POST:接收 POST 方式参数(请求体)。

php

// 1. 接收 GET 参数(AJAX 用 GET 发送:test.php?username=张三&age=18)
$username = $_GET["username"];
$age = $_GET["age"];

// 2. 接收 POST 参数(AJAX 用 POST 发送,参数在 send 中)
$username = $_POST["username"];
$age = $_POST["age"];

// 3. 接收数组参数(如多选框,前端 name 需加 []:name="hobby[]")
$hobby = $_POST["hobby"]; // 数组:["篮球", "编程"]
(3)JSON 数据交互(前后端标准格式)

AJAX 与 PHP 交互常用 JSON 格式,需用 PHP 的 json_encode(数组转 JSON)和 json_decode(JSON 转数组):

php

// 1. PHP 数组转 JSON(返回给 AJAX)
$user = array(
  "name" => "张三",
  "age" => 18,
  "hobby" => array("篮球", "编程")
);
$jsonStr = json_encode($user); // 转 JSON 字符串
echo $jsonStr; // 输出:{"name":"张三","age":18,"hobby":["篮球","编程"]}

// 2. 接收 AJAX 发送的 JSON 数据(需用 file_get_contents 读取请求体)
$jsonStr = file_get_contents("php://input");
$user = json_decode($jsonStr, true); // 转关联数组(true 表示数组,默认对象)
echo $user["name"]; // 输出:张三
(4)引入外部文件(代码复用)

通过 include/require 引入外部 PHP 文件(如公共配置、工具函数):

函数 功能 差异
include 引入文件,报错仅警告 适合非必需文件(如可选模块)
require 引入文件,报错终止执行 适合必需文件(如配置文件)
include_once 同 include,但仅引入一次 防止重复引入导致代码冗余
require_once 同 require,但仅引入一次 防止重复引入导致代码冗余

php

// 引入配置文件
require_once "config.php";

2. JSON-Server:快速搭建模拟后端

当后端未开发完成时,用 JSON-Server 可快速生成模拟 API,支持完整 RESTful 操作。

2.1 安装与启动
  • 前置条件:安装 Node.js(node -v 验证)。

  • 安装 JSON-Server

    bash

    # 全局安装
    npm install -g json-server
    
    # 查看版本(验证安装)
    json-server --version
    
    # 若最新版本有问题,安装稳定旧版本(如 0.17.3)
    npm uninstall -g json-server
    npm install -g json-server@0.17.3
    
  • 创建数据源:在项目目录创建 db.json(模拟数据库):

    json

    {
      "student": [
        { "id": 1000, "uname": "小明", "class": "web前端", "age": 19 },
        { "id": 1001, "uname": "小红", "class": "java开发", "age": 20 }
      ],
      "tableList": ["首页", "公司概况", "云和教育"]
    }
    
  • 启动服务:在 db.json 所在目录执行:

    bash

    # 基本启动(默认端口 3000)
    json-server --watch db.json
    
    # 自定义端口(如 3300)
    json-server --watch db.json --port 3300
    
  • 访问测试:http://localhost:3000/student 可查看所有学生数据。

2.2 RESTful API 操作(增删改查)

JSON-Server 支持标准 RESTful 接口,直接通过 URL 和请求方法操作数据:

操作 请求方法 URL 示例 说明
获取所有资源 GET /student 返回 student 数组
获取单个资源 GET /student/1000 返回 ID 为 1000 的学生
添加资源 POST /student 新增学生(无需传 ID,自动生成)
全量更新 PUT /student/1000 覆盖更新 ID 1000 的学生(需传所有字段)
局部更新 PATCH /student/1000 仅更新指定字段(如只改 age)
删除资源 DELETE /student/1000 删除 ID 1000 的学生
2.3 高级功能(分页、排序、查询)
  • 分页_page(页码)+ _per_page(每页条数):

    plaintext

    http://localhost:3000/student?_page=1&_per_page=2
    
  • 排序_sort(排序字段)+ _order(asc 升序 /desc 降序):

    plaintext

    http://localhost:3000/student?_sort=age&_order=desc
    
  • 条件查询:直接通过字段名过滤:

    plaintext

    # 查询班级为 "web前端" 的学生
    http://localhost:3000/student?class=web前端
    
  • 模糊查询(0.17.x 版本支持):字段名_like

    plaintext

    # 查询姓名包含 "小" 的学生
    http://localhost:3000/student?uname_like=小
    

AJAX 高级应用:懒加载

1. 懒加载原理

懒加载(延迟加载)是优化长列表性能的核心方案,原理是:

  • 初始仅加载 “可视区域” 内的资源(如图片、列表数据)。
  • 当页面滚动时,判断资源是否进入可视区域,若进入则加载。
  • 核心:减少初始加载的资源量,提升首屏渲染速度。

2. 实现图片懒加载(AJAX 配合滚动监听)

html

预览

<!DOCTYPE html>
<html lang="zh-***">
<head>
  <meta charset="UTF-8">
  <title>图片懒加载示例</title>
  <style>
    .img-list { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; width: 1000px; margin: 0 auto; padding: 20px; }
    .img-item { height: 200px; background: #f5f5f5; overflow: hidden; }
    .img-item img { width: 100%; height: 100%; object-fit: cover; }
  </style>
</head>
<body>
  <div class="img-list" id="img-list"></div>

  <script>
    var imgList = document.getElementById("img-list");
    var page = 1; // 当前页码
    var isLoading = false; // 防止重复请求的锁

    // 1. 初始加载第一页图片
    loadImages(page);

    // 2. 监听滚动事件,实现懒加载
    window.addEventListener("scroll", function () {
      // 当滚动到“可视区域底部+200px”时加载下一页
      var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
      var windowHeight = document.documentElement.clientHeight;
      var documentHeight = document.documentElement.scrollHeight;

      if (scrollTop + windowHeight + 200 >= documentHeight && !isLoading) {
        page++;
        loadImages(page);
      }
    });

    // 加载图片的 AJAX 函数
    function loadImages(page) {
      isLoading = true; // 上锁,防止重复请求
      ajax({
        method: "GET",
        url: "https://www.fastmock.site/mock/xxx/api/images", // FastMock 模拟接口
        data: { page: page, limit: 9 }, // 每页加载 9 张图
        su***ess: function (responseText) {
          var res = JSON.parse(responseText);
          var images = res.data;
          // 渲染图片到页面
          renderImages(images);
          isLoading = false; // 解锁
        },
        error: function () {
          console.error("图片加载失败");
          isLoading = false; // 解锁
        }
      });
    }

    // 渲染图片列表
    function renderImages(images) {
      var html = "";
      images.forEach(img => {
        // 初始用占位图,真实地址存放在 data-src 中
        html += `
          <div class="img-item">
            <img src="placeholder.png" data-src="${img.url}" alt="图片">
          </div>
        `;
      });
      imgList.innerHTML += html;

      // 检查已渲染的图片是否进入可视区域,若进入则加载真实图片
      checkImagesInView();
    }

    // 检查图片是否进入可视区域,加载真实图片
    function checkImagesInView() {
      var imgs = document.querySelectorAll(".img-item img");
      imgs.forEach(img => {
        // 若已加载过,跳过
        if (img.src === img.dataset.src) return;

        // 获取图片位置信息
        var rect = img.getBoundingClientRect();
        var windowHeight = document.documentElement.clientHeight;

        // 若图片顶部 <= 可视区域高度(进入可视区域),加载真实图片
        if (rect.top <= windowHeight) {
          img.src = img.dataset.src; // 替换为真实地址
          // 可选:添加加载动画
          img.style.opacity = 0;
          img.onload = function () {
            img.style.transition = "opacity 0.3s";
            img.style.opacity = 1;
          };
        }
      });
    }

    // 通用 AJAX 函数(同上文封装)
    function ajax(options) { /* 此处省略,同上文封装代码 */ }
  </script>
</body>
</html>

关键细节:
  • 占位图:初始用占位图(如灰色背景),真实图片地址存放在 data-src 属性中,避免初始加载大量图片。
  • 滚动监听:通过 scroll 事件判断页面滚动位置,当接近底部时加载下一页。
  • 防重复请求:用 isLoading 锁控制,避免滚动时多次触发请求。

转载请说明出处内容投诉
CSS教程网 » JavaScript AJAX

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买