一、JSON(JavaScript Object Notation)
1. 数据类型与语法细节
支持的数据类型:
基本类型:字符串(需用双引号)、数字、布尔值(true/false
)、null
。
复杂类型:数组([]
)、对象({}
)。
严格语法规范:
键名必须用双引号包裹(如 "name": "张三"
)。
数组元素用逗号分隔,最后一个元素后不能有多余逗号。
数字不能以0
开头(如012
会被解析为12
),不支持八进制 / 十六进制表示。
特殊场景示例:
json
{
"timestamp": 1686528000,
"isAdmin": null,
"emptyArray": [],
"nestedObject": {
"nestedArray": [1, 2, {"key": "value"}]
},
"escapedString": "Hello "World" \n Newline" // 转义字符:", /, , f,
,
,
}
2. JSON 与 JavaScript 对象的区别
特性 | JSON | JavaScript 对象 |
---|---|---|
语法限制 | 键名必须用双引号 | 键名可省略引号(非字符串键) |
数据类型 | 无函数、Symbol、Date 等 | 支持全部 JS 数据类型 |
序列化 | JSON.stringify() |
需手动处理复杂类型 |
原型链 | 不保留原型链 | 包含原型链属性 |
3. JSON 解析与序列化进阶
循环引用处理:
javascript
const obj = { name: '循环对象' };
obj.self = obj;
// JSON.stringify(obj) 会报错
// 解决方案:使用replacer函数过滤循环引用
JSON.stringify(obj, (key, value) => {
if (value === obj) return '[Circular Reference]';
return value;
});
大 JSON 数据处理:
分段解析:使用JSON.parse()
的reviver
参数逐步处理。
流式解析:Node.js 中可用JSONStream
库处理 GB 级 JSON 文件。
JSON Schema 验证:
使用ajv
等库验证 JSON 数据格式,例如:
javascript
const Ajv = require('ajv');
const ajv = new Ajv();
const schema = {
type: 'object',
properties: {
name: { type: 'string' },
age: { type: 'number', minimum: 18 }
},
required: ['name', 'age']
};
const valid = ajv.validate(schema, { name: '李四', age: 20 });
if (!valid) console.log(ajv.errors);
二、AJAX(Asynchronous JavaScript and XML)
1. XMLHttpRequest(XHR)完整 API
核心方法与属性:
open(method, url, async)
:配置请求方法、URL 和异步模式。
setRequestHeader(name, value)
:设置请求头(如Content-Type: application/json
)。
send(data)
:发送请求(GET 请求data
为 null,POST 请求传入 JSON 字符串)。
readyState
:请求状态(0 – 未初始化,1 – 已 open,2 – 已接收头,3 – 处理中,4 – 已完成)。
status
:HTTP 状态码(200 – 成功,404 – 未找到,500 – 服务器错误)。
完整请求示例:
javascript
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/user', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer token123');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
console.log('请求成功:', xhr.responseText);
} else {
console.error('请求失败:', xhr.status, xhr.statusText);
}
}
};
const userData = { name: '张三', email: 'zhangsan@example.com' };
xhr.send(JSON.stringify(userData));
2. Fetch API vs. XHR
特性 | Fetch API | XHR |
---|---|---|
API 设计 | Promise 链式调用,更简洁 | 回调函数驱动,逻辑碎片化 |
默认行为 | 不携带 Cookies | 自动携带同源 Cookies |
错误处理 | 仅网络错误会 reject,4xx/5xx 需手动处理 | 所有请求状态通过回调处理 |
取消请求 | 使用AbortController |
xhr.abort() |
流处理 | 支持响应体分块读取 | 需完整接收后处理 |
Fetch API 示例(带取消功能):
javascript
const controller = new AbortController();
const signal = controller.signal;
fetch('/api/data', {
method: 'GET',
signal,
headers: { 'Content-Type': 'application/json' }
})
.then(response => {
if (!response.ok) throw new Error(`HTTP错误: ${response.status}`);
return response.json();
})
.then(data => console.log('数据:', data))
.catch(error => {
if (error.name === 'AbortError') {
console.log('请求已取消');
} else {
console.error('请求失败:', error);
}
});
// 5秒后取消请求
setTimeout(() => controller.abort(), 5000);
3. Axios 实战进阶
拦截器应用:
javascript
import axios from 'axios';
// 请求拦截器(添加token)
axios.interceptors.request.use(
config => {
const token = localStorage.getItem('token');
if (token) config.headers.Authorization = `Bearer ${token}`;
return config;
},
error => Promise.reject(error)
);
// 响应拦截器(处理401未授权)
axios.interceptors.response.use(
response => response,
error => {
if (error.response && error.response.status === 401) {
localStorage.removeItem('token');
var test = '/login';
}
return Promise.reject(error);
}
);
// 发送请求
axios.get('/api/products', {
params: { category: 'electronics', limit: 10 },
timeout: 5000 // 请求超时时间
})
.then(res => console.log(res.data))
.catch(err => console.error(err));
三、JSON 与 AJAX 结合的高级场景
1. 复杂数据交互模式
分页加载与无限滚动:
javascript
let page = 1;
const loadMoreData = () => {
axios.get('/api/posts', {
params: { page, perPage: 20 }
})
.then(res => {
const posts = res.data;
// 渲染posts到页面
posts.forEach(post => renderPost(post));
page++;
// 检查是否还有更多数据
if (posts.length < 20) {
document.getElementById('load-more').disabled = true;
document.getElementById('load-more').textContent = '没有更多内容';
}
})
.catch(err => console.error('加载失败', err));
};
// 滚动到底部时触发加载
window.addEventListener('scroll', () => {
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 100) {
loadMoreData();
}
});
WebSocket 与 AJAX 协同:
AJAX 用于初始化数据加载和认证。
WebSocket 用于实时数据推送(如聊天消息、通知)。
2. 性能优化策略
请求合并(Batching):
使用Promise.all
合并多个请求:
javascript
const fetchData = async () => {
try {
const [users, posts, comments] = await Promise.all([
axios.get('/api/users'),
axios.get('/api/posts'),
axios.get('/api/comments')
]);
// 处理合并后的数据
renderDashboard(users.data, posts.data, comments.data);
} catch (error) {
console.error('数据加载失败', error);
}
};
防抖与节流:
javascript
// 搜索框防抖(输入停止300ms后发送请求)
function debounce(func, wait) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
const searchInput = document.getElementById('search-input');
const debouncedSearch = debounce(async (query) => {
if (!query.trim()) return;
const response = await axios.get('/api/search', {
params: { q: query }
});
renderSearchResults(response.data);
}, 300);
searchInput.addEventListener('input', e => debouncedSearch(e.target.value));
3. 安全与跨域解决方案
CORS 完整配置(Node.js 示例):
javascript
// Express服务器配置CORS
const express = require('express');
const app = express();
app.use((req, res, next) => {
// 允许的域名(*表示所有域名,生产环境建议指定具体域名)
res.setHeader('Access-Control-Allow-Origin', '*');
// 允许的请求方法
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
// 允许的请求头
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
// 预检请求缓存时间(秒)
res.setHeader('Access-Control-Max-Age', '86400');
// 处理OPTIONS预检请求
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
CSRF 防护:
前端从响应头获取 CSRF Token:
javascript
// 从响应头获取X-CSRF-Token
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
// 在AJAX请求中添加Token
axios.defaults.headers.common['X-CSRF-Token'] = csrfToken;
服务器验证 Token(以 Node.js 为例):
javascript
// 使用csurf中间件
const csurf = require('csurf');
const csrfProtection = csurf({ cookie: true });
app.use(csrfProtection);
app.post('/api/transfer', (req, res) => {
// 自动验证请求头中的X-CSRF-Token
if (!req.csrfToken()) {
return res.status(403).send('CSRF token missing');
}
// 处理转账请求...
});
四、前沿技术与发展趋势
1. JSON 相关新技术
JSON5:扩展 JSON 语法,支持注释、单引号、末尾逗号等(如{ /* 注释 */ name: 'JSON5' }
)。
BSON:二进制 JSON,用于 MongoDB 等数据库,支持 Date、ObjectId 等类型。
MessagePack:比 JSON 更小更快的二进制格式,适用于高并发场景(如实时通信)。
2. AJAX 的演进与替代方案
SSE(Server-Sent Events):服务器向客户端推送数据(单向通信),适用于实时通知。
GraphQL:替代 REST API 的查询语言,允许客户端按需获取数据,减少 AJAX 请求次数。
微前端:通过 AJAX 动态加载子应用,实现前端应用的模块化拆分与集成。
3. WebAssembly 与 AJAX 结合
场景:使用 WebAssembly 处理 AJAX 返回的大量数据(如科学计算、图像渲染),提升性能:
javascript
// 加载WebAssembly模块
WebAssembly.instantiateStreaming(fetch('/wasm/processor.wasm'))
.then(({ instance }) => {
const processData = instance.exports.process;
// AJAX获取数据后交给WebAssembly处理
fetch('/api/large-data')
.then(res => res.arrayBuffer())
.then(data => {
const result = processData(new Uint8Array(data));
// 处理结果
renderResult(result);
});
});
五、面试高频问题与最佳实践
1. 常见面试题
JSON 和 JS 对象的区别?(见前文对比表格)
AJAX 请求为什么会有跨域限制?如何解决?(同源策略,CORS/JSONP/ 代理)
Fetch API 相比 XHR 有哪些优势?有哪些缺点?(Promise、流处理;错误处理、Cookies 默认行为)
2. 生产环境最佳实践
错误处理:统一封装请求函数,处理网络错误、超时、4xx/5xx 状态码。
请求取消:使用AbortController
或 Axios 的CancelToken
取消已发出的请求。
缓存策略:结合localStorage
和 HTTP 缓存(Cache-Control
)减少重复请求。
性能监控:使用PerformanceObserver
记录 AJAX 请求耗时,优化慢请求。
通过深入理解 JSON 的数据结构与 AJAX 的异步交互机制,开发者可以构建更高效、更灵活的 Web 应用。随着前端技术的发展,JSON 与 AJAX 的应用场景也在不断扩展,结合新兴技术(如 WebAssembly、Serverless)将进一步提升数据交互的性能与体验。
暂无评论内容