网站

AJAX 简介 | MDN

使用 Fetch | MDN

XMLHttpRequest | MDN

引入

传统网页提交表单后,整个页面会刷新,用户体验差,速度慢。

Ajax 让 JS 可以在不刷新页面的情况下,向服务器发送请求、获取数据、更新页面内容。现代网页的”无刷新”体验基本都是 Ajax 实现的。

正文

定义

定义

Ajax(Asynchronous JavaScript and XML)是一种在浏览器端向服务器发送异步请求的技术,可以不刷新页面就获取或提交数据。

“异步”的意思是发送请求后,JS 不用等服务器回复,可以继续执行后面的代码。

基本流程

用户操作 → JS 发送请求 → 服务器处理 → 服务器返回数据 → JS 更新页面

整个过程页面不会刷新,用户体验更流畅。

传统提交 vs Ajax

对比传统表单提交Ajax
页面刷新会刷新不刷新
用户体验差,白屏等待好,局部更新
数据格式只支持表单数据支持任意格式(JSON、文本等)
实现方式<form> + submitJS 发送请求

fetch() 发送请求

现代浏览器中,最常用的请求方式是 fetch()

GET 请求

fetch("https://api.example.com/users")
  .then(function (response) {
    return response.json();
  })
  .then(function (data) {
    console.log(data);
  });

发送一个 GET 请求,获取 JSON 格式的数据。

POST 请求

fetch("https://api.example.com/users", {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    name: "张三",
    age: 25
  })
})
  .then(function (response) {
    return response.json();
  })
  .then(function (data) {
    console.log(data);
  });

发送一个 POST 请求,把数据以 JSON 格式提交给服务器。

响应处理

fetch() 返回的是一个 Promise 对象。

fetch("https://api.example.com/users")
  .then(function (response) {
    console.log(response.status);
    return response.json();
  })
  .then(function (data) {
    console.log(data);
  });
方法作用
response.json()把响应体解析为 JSON 对象
response.text()把响应体解析为纯文本
response.statusHTTP 状态码(200、404、500 等)
response.ok状态码是否在 200-299 范围内

例子

获取用户列表并显示

<button id="loadBtn">加载用户</button>
<ul id="list"></ul>
const loadBtn = document.querySelector("#loadBtn");
const list = document.querySelector("#list");
 
loadBtn.addEventListener("click", function () {
  fetch("https://api.example.com/users")
    .then(function (response) {
      return response.json();
    })
    .then(function (users) {
      list.innerHTML = "";
      users.forEach(function (user) {
        const li = document.createElement("li");
        li.textContent = user.name;
        list.appendChild(li);
      });
    });
});

点击按钮后,从服务器获取用户数据,动态渲染到列表中,页面不会刷新。

提交评论

<input id="commentInput" type="text" placeholder="写评论">
<button id="submitBtn">发布</button>
<p id="status"></p>
const commentInput = document.querySelector("#commentInput");
const submitBtn = document.querySelector("#submitBtn");
const status = document.querySelector("#status");
 
submitBtn.addEventListener("click", function () {
  const comment = commentInput.value;
 
  if (comment === "") {
    return;
  }
 
  fetch("https://api.example.com/comments", {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ content: comment })
  })
    .then(function (response) {
      return response.json();
    })
    .then(function (data) {
      status.textContent = "评论已发布";
      commentInput.value = "";
    });
});

错误处理

fetch() 只有在网络故障时才会报错,HTTP 错误(404、500)不会自动报错。

fetch("https://api.example.com/users")
  .then(function (response) {
    if (!response.ok) {
      throw new Error("请求失败:" + response.status);
    }
    return response.json();
  })
  .then(function (data) {
    console.log(data);
  })
  .catch(function (error) {
    console.log("出错了:" + error.message);
  });

catch() 用来捕获请求过程中的任何错误。

Ajax 的历史

早期的 Ajax 使用 XMLHttpRequest 对象发送请求,写法比较繁琐。

const xhr = new XMLHttpRequest();
 
xhr.open("GET", "https://api.example.com/users");
xhr.onload = function () {
  if (xhr.status === 200) {
    const data = JSON.parse(xhr.responseText);
    console.log(data);
  }
};
xhr.send();

现代开发中更推荐用 fetch(),写法更简洁。

如果想了解更多,可以查看 JS 网络请求

常见写法

写法作用
fetch(url)发送 GET 请求
fetch(url, { method: "POST", body: … })发送 POST 请求
response.json()解析 JSON 响应
response.text()解析纯文本响应
.then(fn)处理成功的响应
.catch(fn)处理错误

特点

  • Ajax 让页面可以不刷新就获取和提交数据
  • fetch() 是现代浏览器推荐的请求方式
  • 请求是异步的,不会阻塞 JS 代码执行
  • 响应数据通常是 JSON 格式
  • then() 处理成功响应,catch() 处理错误
  • HTTP 错误状态码不会触发 catch(),需要手动检查 response.ok
  • Ajax 请求会受到同源策略限制,跨域请求需要服务器配置 CORS

注意事项

  • fetch() 不会自动把 HTTP 错误(404、500)当作错误抛出
  • 跨域请求需要服务器返回正确的 CORS 头
  • 请求失败时(网络断开),catch() 会被调用
  • fetch() 不支持直接设置超时时间,需要配合 AbortController 实现
  • 频繁发送请求会给服务器增加压力,必要时需要做防抖处理

理解

可以把 Ajax 理解成”偷偷跑腿”。

传统提交表单是:把表格交给前台,前台重新把整个页面给你看。

Ajax 是:让 JS 偷偷跑去问服务器要数据,拿到后只改页面上需要改的部分,其他人看不到页面刷新。

我理解 Ajax 的重点是:不刷新页面,用 JS 向服务器要数据,再更新页面

引出

了解了 Ajax 的基本概念后,可以深入学习 JS 网络请求,掌握 fetch()XMLHttpRequest 的更多细节。

Ajax 本质上是异步操作,结合 JS PromiseJS async await 可以写出更清晰的异步代码。