AJAX 如何请求 JSON:从基础到实践的完整指南
在现代 Web 开发中,前端与后端的数据交互是核心环节,AJAX(Asynchronous JavaScript and XML)作为一种异步通信技术,允许在不刷新页面的情况下与服务器交换数据,而 JSON(JavaScript Object Notation)因其轻量级、易解析的特性,已成为 Web 数据交换的主流格式,本文将详细介绍如何使用 AJAX 请求 JSON 数据,从基础概念到代码实践,再到常见问题解决,帮助你这一关键技能。
AJAX 与 JSON:核心概念解析
1 什么是 AJAX?
AJAX(异步 JavaScript 和 XML)并非单一技术,而是利用 XMLHttpRequest(XHR) 对象或 Fetch API,通过 JavaScript 向服务器发送异步请求,并接收服务器响应的技术,核心优势是“异步性”——页面无需刷新即可更新数据,提升用户体验。
2 为什么选择 JSON?
JSON 是一种轻量级的数据交换格式,以键值对("key": "value"
)和数组([]
)组织数据,格式简洁,可读性强,更重要的是,JSON 是 JavaScript 的原生 subset(子集),可通过 JSON.parse()
直接转换为 JavaScript 对象,无需额外解析库,因此成为 AJAX 请求的首选数据格式。
使用 XMLHttpRequest
请求 JSON(传统方式)
XMLHttpRequest
是 AJAX 的基础 API,所有浏览器均支持,适合理解 AJAX 的底层逻辑,以下是完整步骤:
1 创建 XHR 对象
const xhr = new XMLHttpRequest(); // 创建 XHR 实例
2 配置请求
通过 open()
方法设置请求参数:
- 方法:
GET
(获取数据,常用)、POST
(提交数据,需配合请求体) - URL:服务器接口地址(需同源,或服务器支持 CORS)
- 异步:第三个参数设为
true
(默认)表示异步请求
xhr.open('GET', 'https://api.example.com/data', true);
3 设置响应数据类型(可选)
通过 setRequestHeader()
告诉服务器期望返回 JSON 数据,或直接通过 responseType
指定(推荐现代方式):
xhr.responseType = 'json'; // 自动将响应解析为 JS 对象
4 监听请求状态变化
XHR 对象的 readyState
属性表示请求状态,onreadystatechange
事件会在状态变化时触发,重点关注 readyState=4
(请求完成)且 status=200
(成功)的情况:
xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { const data = xhr.response; // 已自动解析为 JS 对象 console.log('请求成功:', data); // 处理数据(如渲染到页面) } else if (xhr.readyState === 4) { console.error('请求失败:', xhr.status); } };
5 发送请求
xhr.send(); // GET 请求时传 null,POST 请求时传请求体(如 JSON 字符串)
6 完整示例
假设后端接口 https://api.example.com/users
返回 JSON 数据:
[ { "id": 1, "name": "Alice", "age": 25 }, { "id": 2, "name": "Bob", "age": 30 } ]
前端请求代码:
const xhr = new XMLHttpRequest(); xhr.open('GET', 'https://api.example.com/users', true); xhr.responseType = 'json'; xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { const users = xhr.response; const userList = document.getElementById('user-list'); users.forEach(user => { const li = document.createElement('li'); li.textContent = `${user.name} (${user.age}岁)`; userList.appendChild(li); }); } else { console.error('请求失败,状态码:', xhr.status); } } }; xhr.send();
使用 Fetch API
请求 JSON(现代推荐)
Fetch API
是 ES2015 引入的现代 Web API,基于 Promise 设计,语法更简洁,支持链式调用,是目前主流的 AJAX 请求方式。
1 基础 GET 请求
fetch()
接收两个参数:请求 URL 和配置对象(可选),默认发送 GET 请求,返回一个 Promise:
fetch('https://api.example.com/users') .then(response => { // 判断 HTTP 状态码(200-299 为成功) if (!response.ok) { throw new Error(`HTTP 错误!状态码: ${response.status}`); } // response.json() 返回一个 Promise,解析响应体为 JSON return response.json(); }) .then(data => { console.log('请求成功:', data); // 处理数据 }) .catch(error => { console.error('请求失败:', error); });
2 POST 请求示例
POST 请求需在配置对象中指定 method
、headers
和 body
:
fetch('https://api.example.com/users', { method: 'POST', headers: { 'Content-Type': 'application/json', // 告诉服务器发送的是 JSON }, body: JSON.stringify({ name: 'Charlie', age: 28 }), // 将 JS 对象转为 JSON 字符串 }) .then(response => response.json()) .then(data => { console.log('创建成功:', data); }) .catch(error => { console.error('创建失败:', error); });
3 使用 async/await
优化可读性
结合 async/await
可避免回调地狱,使异步代码更像同步代码:
async function fetchUsers() { try { const response = await fetch('https://api.example.com/users'); if (!response.ok) { throw new Error(`HTTP 错误!状态码: ${response.status}`); } const users = await response.json(); console.log('用户数据:', users); return users; } catch (error) { console.error('获取用户失败:', error); return null; } } // 调用函数 fetchUsers().then(users => { if (users) { // 进一步处理数据 } });
跨域请求(CORS)与解决方案
当 AJAX 请求的 URL 与当前页面不同源(协议、域名、端口任一不同)时,浏览器会阻止请求,以避免安全风险(同源策略),此时需要服务器配合 CORS(Cross-Origin Resource Sharing,跨域资源共享)。
1 CORS 原理
服务器通过响应头 Access-Control-Allow-Origin
告诉浏览器哪些域名可以访问资源:
Access-Control-Allow-Origin: *
:允许所有域名访问(不推荐生产环境)Access-Control-Allow-Origin: https://your-frontend.com
:仅允许指定域名访问
2 前端注意事项
- 简单请求(如 GET、POST,且请求头无自定义字段)会直接发送,服务器需返回正确的 CORS 头。
- 非简单请求(如 PUT、DELETE,或带自定义头的请求)会先发送
OPTIONS
预检请求,服务器需响应Access-Control-Allow-Methods
和Access-Control-Allow-Headers
。
3 解决跨域的实践方法
(1)服务器配置 CORS(推荐)
以 Node.js(Express)为例:
const express = require('express'); const app = express(); app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', 'https://your-frontend.com'); res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); next(); }); app.get('/api/data', (req, res) => { res.json({ message: '这是跨域数据' }); }); app.listen(3000, () => { console.log('服务器运行在 http://localhost:3000'); });
(2)代理服务器(适用于开发环境)
开发时可通过前端工具(如 Vite、Webpack)或 Nginx 设置代理,将请求转发到同源接口,避免跨域问题。
Vite 代理配置示例(vite.config.js
):
export default { server: { proxy: { '/api': { target: 'https://api.example.com', // 后端服务器地址 changeOrigin: true, // 修改请求头中的 origin rewrite: (path) => path.replace(/^\/api/, '') // 可选:重写路径 }
还没有评论,来说两句吧...