如何用JavaScript获取请求JSON数据:从基础到实践
在Web开发中,JavaScript获取JSON(JavaScript Object Notation)数据是一项核心技能,无论是调用后端API、读取本地配置文件,还是处理第三方服务数据,JSON请求方法都是开发者的必备能力,本文将系统介绍JavaScript获取JSON数据的多种方式,从基础的fetch API到兼容性更好的XMLHttpRequest,再到处理跨域、错误场景等实战技巧,帮助你全面这一技能。
JSON与HTTP请求:基础概念
在开始之前,我们先明确两个核心概念:
JSON是什么?
JSON是一种轻量级的数据交换格式,以键值对("key": value)为核心结构,支持字符串、数字、布尔值、数组、对象等数据类型,因其可读性强、解析效率高,成为Web API通信的主流数据格式(相比XML更简洁),示例:
{
"name": "张三",
"age": 25,
"hobbies": ["阅读", "编程"],
"isStudent": true
}
HTTP请求与JSON的关系
后端服务通常通过HTTP请求(GET/POST/PUT/DELETE等)返回JSON数据,前端JavaScript需要发送HTTP请求,接收服务器返回的JSON响应,并将其解析为可操作的JavaScript对象。
现代方法:使用fetch API
fetch是ES2015(ES6)引入的现代Web API,用于发起网络请求,它基于Promise,语法简洁,是目前获取JSON数据的主流方式。
基本语法
fetch(url, options)接受两个参数:
url:请求的目标地址(字符串)。options:可选的配置对象(如请求方法、headers、body等)。
默认发起GET请求,服务器返回的响应是Response对象,需通过.json()方法解析为JSON数据(注意:.json()返回Promise,需链式调用then)。
实战示例:GET请求获取JSON
假设后端API地址为https://api.example.com/user/1,返回用户信息的JSON数据:
// 发起GET请求获取JSON数据
fetch('https://api.example.com/user/1')
.then(response => {
// 检查响应状态码(200-299表示成功)
if (!response.ok) {
throw new Error(`HTTP错误!状态码:${response.status}`);
}
// 使用.json()解析响应体为JSON对象
return response.json();
})
.then(data => {
// 解析成功,data即为JavaScript对象
console.log('用户数据:', data);
// data.name、data.age可直接使用
})
.catch(error => {
// 捕获请求或解析过程中的错误
console.error('获取数据失败:', error);
});
POST请求发送JSON数据
如果需要向服务器提交JSON数据(如创建用户),需设置Content-Type为application/json,并通过JSON.stringify将对象转为JSON字符串:
const userData = {
name: '李四',
age: 30,
hobbies: ['运动', '音乐']
};
fetch('https://api.example.com/users', {
method: 'POST', // 请求方法
headers: {
'Content-Type': 'application/json' // 声明发送JSON数据
},
body: JSON.stringify(userData) // 将对象转为JSON字符串
})
.then(response => response.json())
.then(data => {
console.log('创建用户成功:', data);
})
.catch(error => {
console.error('提交数据失败:', error);
});
fetch的注意事项
- 响应状态码:即使服务器返回404、500等错误状态码,
fetch不会自动抛出错误,需手动检查response.ok(状态码200-299)或response.status。 - 解析时机:
response.json()只能调用一次,多次调用会抛出错误(因为响应体已被消耗)。 - 兼容性:IE浏览器不支持
fetch,需引入polyfill(如whatwg-fetch)。
传统方法:使用XMLHttpRequest
XMLHttpRequest(简称XHR)是早期的Web API,所有浏览器均支持,适用于需要兼容旧环境(如IE)的场景,它通过事件监听处理请求状态变化。
基本步骤
- 创建
XMLHttpRequest实例。 - 调用
open()方法初始化请求(方法、URL、是否异步)。 - 设置
onreadystatechange事件监听,监听请求状态变化(readyState)。 - 发送请求
send()。 - 解析响应数据(需设置
responseType为'json'或手动解析)。
实战示例:GET请求获取JSON
const xhr = new XMLHttpRequest();
// 初始化请求(GET请求,异步true)
xhr.open('GET', 'https://api.example.com/user/1', true);
// 设置响应类型为json(自动解析)
xhr.responseType = 'json';
// 监听请求状态变化
xhr.onreadystatechange = function() {
// readyState=4表示请求完成,status=200表示成功
if (xhr.readyState === 4 && xhr.status === 200) {
console.log('用户数据:', xhr.response); // xhr.response已自动解析为对象
} else if (xhr.readyState === 4) {
console.error('请求失败,状态码:', xhr.status);
}
};
// 发送请求
xhr.send();
POST请求发送JSON数据
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/users', true);
// 设置请求头,声明发送JSON数据
xhr.setRequestHeader('Content-Type', 'application/json');
// 监听请求完成事件
xhr.onload = function() {
if (xhr.status === 201) { // 201表示创建成功
console.log('创建用户成功:', xhr.response);
} else {
console.error('提交失败:', xhr.status);
}
};
// 发送JSON字符串
const userData = { name: '王五', age: 28 };
xhr.send(JSON.stringify(userData));
XMLHttpRequest的优缺点
- 优点:兼容性极好(支持IE7+),支持同步请求(
open第三个参数设为false,但不推荐,会阻塞页面)。 - 缺点:语法繁琐(需手动管理事件监听),基于回调而非Promise,代码可读性较差。
进阶场景:处理跨域请求
跨域资源共享(CORS)是浏览器安全策略,当请求的协议、域名、端口任一与当前页面不同时,浏览器会阻止跨域请求(除非服务器允许)。
跨域问题的解决
- 服务器端配置:服务器需在响应头中添加
Access-Control-Allow-Origin字段(如Access-Control-Allow-Origin: *允许所有域名,或指定域名如https://yourdomain.com)。 - 代理服务器:若无法修改后端代码,可通过前端代理(如Nginx、Vite开发服务器)转发请求,将跨域请求转为同域请求。
跨域请求示例(fetch)
fetch('https://another-api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('跨域请求失败:', error));
若服务器未配置CORS,浏览器会报错:Access to fetch at '...' from origin '...' has been blocked by CORS policy。
错误处理与最佳实践
常见错误类型
- 网络错误:如断网、域名解析失败(
fetch的catch会捕获)。 - HTTP错误:状态码404(未找到)、500(服务器错误)等(需手动检查
response.ok)。 - JSON解析错误:服务器返回非JSON数据(如HTML错误页面),调用
.json()会抛出错误(需用try-catch包裹)。
完善的错误处理(fetch)
async function fetchUserData(userId) {
try {
const response = await fetch(`https://api.example.com/user/${userId}`);
// 检查响应状态
if (!response.ok) {
throw new Error(`请求失败,状态码:${response.status}`);
}
// 尝试解析JSON
const data = await response.json();
return data;
} catch (error) {
// 区分网络错误和解析错误
if (error instanceof SyntaxError) {
console.error('JSON解析失败:', error);
} else {
console.error('请求错误:', error);
}
throw error; // 可以选择向上抛出,或返回默认值
}
}
//


还没有评论,来说两句吧...