当网页需要加载商品、提交表单或刷新评论时,必须与服务器进行通信。这种“不刷新页面即可获取数据并更新界面”的能力,是现代 Web 开发的核心。本文将重点讲解前端如何主动发起 HTTP 请求,并把数据渲染到页面上。
1. 为什么需要前后端通信?
网页内容通常是动态获取的(如电商列表、用户昵称、评论等)。前端负责界面交互与渲染,后端负责业务逻辑与数据存储,两者最常见的沟通方式就是 HTTP 接口通信。
2. 什么是 Ajax?
Ajax(Asynchronous JavaScript and XML)是一种开发思想:使用 JavaScript 在后台发请求,并在不刷新页面的情况下局部更新内容。
它并非特定 API,常见实现包括早期的 XMLHttpRequest、现代浏览器原生的 fetch 以及第三方库 axios。
3. Fetch 基础使用
fetch 是浏览器原生 API,基于 Promise,推荐配合 async/await 使用,语法更加现代。
3.1 发送 GET 请求
async function getData() {
try {
// 发起 GET 请求
const response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
// 把响应体解析成 JSON
const data = await response.json(); // 解析为 JSON
console.log(data);
} catch (error) {
console.error("网络错误:", error);
}
}
3.2 发送 POST 请求与携带参数
async function postData() {
try {
const response = await fetch("https://api.example.com/users", {
// 指定请求方法
method: "POST",
headers: {
"Content-Type": "application/json" // 声明发送的数据格式
},
body: JSON.stringify({ username: "alice", password: "123" }) // 提交的数据体
});
const data = await response.json();
console.log("创建结果:", data);
} catch (error) {
console.error("提交失败:", error);
}
}
4. 避坑:Response 对象与错误处理
fetch() 返回的并非最终数据,而是一个 Response 对象,包含 status (状态码)、ok (是否成功) 等信息。
核心坑点: 即使服务器返回 404 或 500,fetch 也不会进入 catch(只有断网等网络层错误才会)。因此必须手动检查 response.ok:
const response = await fetch("https://api.example.com/data");
// fetch 遇到 404/500 不会自动抛错,需要自己判断
if (!response.ok) {
throw new Error(`请求失败,状态码:${response.status}`);
}
// 确认成功后再读取数据
const data = await response.json();
5. 完整实战:数据渲染与状态处理
真实项目中,请求接口必须处理 加载中、成功(含空数据)、失败 三种状态。
<div id="app"></div>
<script>
async function loadArticles() {
const app = document.getElementById("app");
app.innerHTML = "加载中..."; // 1. 加载状态
try {
const res = await fetch("https://jsonplaceholder.typicode.com/posts");
if (!res.ok) throw new Error("加载失败");
// 把响应结果解析成数组
const articles = await res.json();
if (articles.length === 0) {
app.innerHTML = "暂无数据"; // 2. 空状态
return;
}
// 3. 成功渲染
app.innerHTML = articles.slice(0, 5).map(a => `<p>${a.title}</p>`).join("");
} catch (error) {
app.innerHTML = `请求错误:${error.message}`; // 4. 错误状态
}
}
loadArticles();
</script>
6. 传统 Ajax (XMLHttpRequest) 核心知识
为了扎实基础,理解传统的 XHR 是必不可少的。它通过事件和状态码管理请求。
6.1 XHR 生命周期 (readyState)
0(UNSENT):未初始化。已创建 XHR 对象,未调用open()。1(OPENED):已打开。已调用open(),未调用send()。2(HEADERS_RECEIVED):已接收响应头。3(LOADING):正在下载响应体。4(DONE):请求完成。
6.2 经典封装与 Fetch 的区别
传统 XHR 依赖回调(如 onreadystatechange 或 onload),易产生回调地狱。现代开发常用 Promise 封装 XHR(这也是 axios 的底层原理)。
相比 XHR,fetch 的核心优势在于:
- 语法更简洁:基于 Promise,契合
async/await。 - 关注点分离:请求与响应头/体解析分离,更加语义化。
- 默认不带 Cookie:跨域默认不携带凭证,需显式配置。
7. 常见配置与排错指南
7.1 常见请求配置
- 请求头配置:常用于传递 Token(
Authorization: Bearer <token>)。 - 超时控制:原生
fetch需结合AbortController实现;若业务复杂,推荐直接使用axios。
7.2 常见接口问题
- 跨域拦截:需后端配置 CORS 允许跨域。
- 401 / 403:未登录或身份失效 / 无权限访问。
- 404 / 500:接口地址错误 / 服务器内部异常。
- 数据格式报错:养成先
console.log(data)看清返回结构的习惯。
8. 总结:Fetch、Ajax 与 Axios
- Ajax:一种“异步请求数据、局部更新页面”的开发思想。
- fetch:现代浏览器原生的具体 API。
- axios:基于 Promise 封装的第三方库,项目中最为常见。
掌握 HTTP 请求流程和 DOM 渲染后,网页才真正具备了连接真实业务数据的能力。接下来,即可平滑过渡到 Vue/React 等现代框架的工程化开发中。