一、前言
在前后端分离开发模式中,AJAX 是实现页面无刷新数据交互的核心技术,而 XMLHttpRequest(简称 XHR)正是浏览器原生支持的 AJAX 底层 API。
相比于现代的 fetch 和 Axios,XMLHttpRequest 兼容性更好(支持 IE 等老旧浏览器),也是理解 AJAX 通信原理的基础。本文将通过 GET 数据查询 和 POST 数据提交 两个核心场景,带你从零掌握 XMLHttpRequest 的使用方法。
二、核心概念回顾
1. XMLHttpRequest 作用
在不刷新整个页面的情况下,向服务器发送 HTTP 请求、接收响应数据,并更新页面局部内容。
2. 核心流程
plaintext
创建 XHR 实例 → 配置请求参数 → 设置请求头 → 监听状态变化 → 发送请求 → 处理响应
3. 关键状态码
| 状态码 | 描述 |
|---|---|
readyState = 0 |
未初始化:实例已创建,未调用 open() |
readyState = 1 |
已打开:调用 open(),未调用 send() |
readyState = 2 |
已发送:调用 send(),已接收响应头 |
readyState = 3 |
正在接收:正在加载响应体数据 |
readyState = 4 |
请求完成:响应数据已全部接收(核心判断条件) |
HTTP 响应状态码:200~299 表示请求成功,4xx 客户端错误,5xx 服务端错误。
三、实战案例 1:GET 请求(查询数据)
GET 请求用于从服务器获取数据,参数通过 URL 拼接(查询字符串)传递,适用于数据查询、列表加载等场景。
1. 完整代码
html
预览
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>XHR GET 请求示例</title>
<style>
#result {
margin-top: 20px;
padding: 15px;
border: 1px solid #eee;
border-radius: 4px;
}
.success {
border-color: #4CAF50;
color: #388E3C;
}
.error {
border-color: #f44336;
color: #D32F2F;
}
</style>
</head>
<body>
<h3>XMLHttpRequest GET 请求演示</h3>
<button onclick="sendGetRequest()">点击发送 GET 请求</button>
<div id="result"></div>
<script>
// 发送 GET 请求的函数
function sendGetRequest() {
// 1. 创建 XMLHttpRequest 实例
const xhr = new XMLHttpRequest();
// 2. 配置请求参数:open(method, url, async)
// method: 请求方式 GET/POST
// url: 请求地址(使用 JSONPlaceholder 免费模拟接口)
// async: 是否异步,true(推荐)/false
const url = 'https://jsonplaceholder.typicode.com/todos/1';
xhr.open('GET', url, true);
// 3. 设置请求头(可选,GET 请求一般可省略)
// 告诉服务器期望返回 JSON 格式数据
xhr.setRequestHeader('Accept', 'application/json');
// 4. 监听请求状态变化事件
xhr.onreadystatechange = function() {
// 核心判断:请求完成 + 响应成功
if (xhr.readyState === XMLHttpRequest.DONE) {
const resultDom = document.getElementById('result');
if (xhr.status >= 200 && xhr.status < 300) {
// 5. 处理成功响应数据
const response = JSON.parse(xhr.responseText);
resultDom.className = 'success';
resultDom.innerHTML = `
<p>✅ 请求成功(状态码:${xhr.status})</p>
<p>任务 ID:${response.id}</p>
<p>任务标题:${response.title}</p>
<p>任务状态:${response.completed ? '已完成' : '未完成'}</p>
`;
} else {
// 6. 处理失败情况
resultDom.className = 'error';
resultDom.innerHTML = `
<p>❌ 请求失败(状态码:${xhr.status})</p>
<p>错误信息:${xhr.statusText}</p>
`;
}
}
};
// 7. 发送请求(GET 请求 send 参数为 null 或省略)
xhr.send(null);
}
</script>
</body>
</html>
2. 关键要点
- 异步请求 :
open()第三个参数设为true,请求过程中不会阻塞页面渲染。 - 响应解析 :
xhr.responseText是服务器返回的文本数据,需用JSON.parse()转为 JS 对象。 - 错误处理 :必须同时判断
readyState === 4和status范围,避免提前处理不完整的响应。
3. 运行效果
- 将代码保存为
xhr-get.html,用浏览器打开。 - 点击按钮,页面下方会显示从接口获取的任务数据,成功时边框为绿色,失败时为红色。
四、实战案例 2:POST 请求(提交数据)
POST 请求用于向服务器提交数据,参数放在请求体中,安全性更高,支持提交大量数据,适用于表单提交、创建资源等场景。
1. 完整代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>XHR POST 请求示例</title>
<style>
#result {
margin-top: 20px;
padding: 15px;
border: 1px solid #eee;
border-radius: 4px;
}
.success {
border-color: #4CAF50;
color: #388E3C;
}
.error {
border-color: #f44336;
color: #D32F2F;
}
</style>
</head>
<body>
<h3>XMLHttpRequest POST 请求演示</h3>
<button onclick="sendPostRequest()">点击发送 POST 请求</button>
<div id="result"></div>
<script>
// 发送 POST 请求的函数
function sendPostRequest() {
// 1. 创建 XHR 实例
const xhr = new XMLHttpRequest();
// 2. 配置请求参数
const url = 'https://jsonplaceholder.typicode.com/posts';
xhr.open('POST', url, true);
// 3. 设置请求头(POST 请求必须配置!)
// 声明请求体为 JSON 格式
xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
// 4. 监听状态变化
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
const resultDom = document.getElementById('result');
if (xhr.status >= 200 && xhr.status < 300) {
const response = JSON.parse(xhr.responseText);
resultDom.className = 'success';
resultDom.innerHTML = `
<p>✅ 请求成功(状态码:${xhr.status})</p>
<p>新建文章 ID:${response.id}</p>
<p>文章标题:${response.title}</p>
<p>文章内容:${response.body}</p>
`;
} else {
resultDom.className = 'error';
resultDom.innerHTML = `
<p>❌ 请求失败(状态码:${xhr.status})</p>
<p>错误信息:${xhr.statusText}</p>
`;
}
}
};
// 5. 准备请求体数据
const postData = {
title: 'XMLHttpRequest 实战教程',
body: '这是一篇通过 POST 请求提交的文章',
userId: 1
};
// 6. 发送请求:将 JS 对象转为 JSON 字符串
xhr.send(JSON.stringify(postData));
}
</script>
</body>
</html>
2. 关键要点
- 请求头配置 :POST 请求必须设置
Content-Type,告诉服务器如何解析请求体:application/json:JSON 格式(前后端分离首选)。application/x-www-form-urlencoded:表单格式(如name=test&age=20)。
- 请求体处理 :需用
JSON.stringify()将 JS 对象转为 JSON 字符串,作为send()的参数。 - 模拟接口 :
JSONPlaceholder是免费的 REST API,可用于测试 POST 请求,会返回提交的数据 + 自动生成的id。
五、GET vs POST 核心区别
| 特性 | GET | POST |
|---|---|---|
| 用途 | 查询数据 | 提交数据 |
| 参数位置 | URL 拼接 | 请求体中 |
| 数据大小 | 受 URL 长度限制(一般 2KB) | 无限制 |
| 安全性 | 低(参数暴露在 URL) | 高(参数隐藏在请求体) |
| 请求头 | 可选设置 | 必须设置 Content-Type |
六、常见问题与解决方案
跨域请求失败
- 原因:浏览器同源策略限制。
- 解决:服务端配置 CORS(跨域资源共享),或使用代理服务器。
JSON 解析报错
- 原因:服务器返回非 JSON 格式数据,或数据格式错误。
- 解决:先打印
xhr.responseText查看原始数据,确认格式正确后再解析。
同步请求阻塞页面
- 原因:
open()第三个参数设为false。 - 解决:优先使用异步请求(
true),避免页面卡死。
七、总结
本文通过两个可直接运行的案例,详细讲解了 XMLHttpRequest 的 GET 和 POST 请求用法,核心要点如下:
- 核心流程:创建实例 → 配置请求 → 设置请求头 → 监听状态 → 发送请求 → 处理响应。
- GET 请求 :用于查询,参数拼 URL,无需设置
Content-Type。 - POST 请求 :用于提交,参数放请求体,必须配置
Content-Type。 - 状态判断 :必须同时满足
readyState === 4和status 200~299才是请求成功。
掌握 XMLHttpRequest 是理解 AJAX 原理的关键,后续学习 fetch 和 Axios 会更加轻松。
📝 博主寄语 :如果本文对你有帮助,欢迎点赞、收藏、关注!你的支持是我持续创作的动力~💬 评论区交流 :你在使用
XMLHttpRequest时遇到过哪些问题?欢迎在评论区分享!