📅 2026-06-15 · 📖 阅读约8分钟 · 🏷️ JSON, 前端开发
JSON完全指南:从入门到最佳实践
什么是JSON?
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,由Douglas Crockford在2000年代初期推广。它基于JavaScript对象语法,但已被所有主流编程语言支持。JSON的设计哲学是简单、可读、易于解析,使其成为Web API事实上的标准数据格式。
JSON支持6种数据类型:字符串(必须用双引号)、数字(整数或浮点数)、布尔值(true/false)、null、对象(键值对集合)和数组(有序列表)。这种简洁的类型系统足以表达绝大多数数据结构。
JSON语法规则
JSON的语法规则看似简单,但严格程度超出很多人预期:
- 键名必须用双引号:{name: "value"} 是非法的,必须写成 {"name": "value"}
- 不支持注释:标准JSON不允许任何形式的注释
- 不能有尾逗号:[1, 2, 3,] 是非法的
- 字符串必须用双引号:单引号不合法
- 数字格式严格:不支持NaN、Infinity、前导零(01)
这些严格规则意味着你不能把JavaScript对象直接当作JSON使用。必须通过JSON.stringify()序列化后才能成为合法的JSON字符串。
JavaScript中的JSON操作
// 序列化:对象 → JSON字符串
const user = { name: "张三", age: 25, skills: ["JS", "Python"] };
const jsonStr = JSON.stringify(user);
// '{"name":"张三","age":25,"skills":["JS","Python"]}'
// 美化输出
JSON.stringify(user, null, 2);
// 解析:JSON字符串 → 对象
const parsed = JSON.parse(jsonStr);
// 安全解析(错误处理)
function safeParse(str) {
try { return { data: JSON.parse(str), error: null }; }
catch (e) { return { data: null, error: e.message }; }
}
// 自定义序列化(处理Date等特殊类型)
JSON.stringify(user, (key, value) => {
if (value instanceof Date) return value.toISOString();
return value;
});
// 过滤字段
JSON.stringify(user, ['name', 'age']); // 只序列化name和age
JSON API设计最佳实践
设计RESTful API的JSON响应时,遵循一致的规范可以大幅提升开发效率:
- 统一响应格式:{"code": 0, "message": "success", "data": {...}}
- 使用驼峰命名:userName而非user_name(API层面)
- 日期用ISO 8601:"2024-01-15T08:30:00Z"
- 空值处理:不存在的字段返回null而非空字符串
- 分页格式:{"items": [...], "total": 100, "page": 1, "pageSize": 20}
JSON的安全注意事项
永远不要使用eval()解析JSON!eval()会执行JSON中的任何JavaScript代码,如果JSON来自不可信的来源,攻击者可以注入恶意代码。始终使用JSON.parse(),它只解析数据,不执行代码。
此外,大整数在JSON中可能丢失精度。JavaScript的Number类型使用IEEE 754双精度浮点数,超过2^53-1的整数无法精确表示。处理ID等大整数时,应使用字符串类型。
JSON的替代方案
虽然JSON是主流,但某些场景下其他格式可能更合适:YAML更易读(适合配置文件),Protocol Buffers更紧凑高效(适合微服务间通信),MessagePack是二进制JSON(适合带宽敏感场景)。选择数据格式时,需要权衡可读性、性能、跨语言支持等因素。在实际项目中,JSON仍然是最通用和最安全的选择。
📅 2026-06-15 · 📖 阅读约7分钟 · 🏷️ Base64, 编码
Base64编码终极指南:原理、应用与注意事项
Base64的本质
Base64不是加密,而是编码。它的作用是将任意二进制数据转换为纯文本字符,使其可以安全地在只支持文本的协议中传输。就像把一幅画翻译成文字描述——信息没有变,只是换了表现形式。
Base64使用64个可打印ASCII字符作为字母表:26个大写字母 + 26个小写字母 + 10个数字 + 加号(+)和斜杠(/)。每3个字节(24位)被分成4组,每组6位,映射到一个字符。因为6位可以表示64种状态(2的6次方 = 64),所以叫"Base64"。
编码原理图解
// "Man" 的Base64编码过程
// 原始字节: M(77) a(97) n(110)
// 二进制: 01001101 01100001 01101110
// 6位分组: 010011 010110 000101 101110
// 十进制: 19 22 5 46
// Base64: T W F n
// 结果: "TWFu"
// 验证
btoa("Man") // "TWFu" ✓
体积膨胀问题
Base64编码后数据体积增加约33%。这是因为3字节变成了4字符。此外,当原始数据长度不是3的倍数时,需要用等号(padding)填充到4的倍数。
这意味着:一个100KB的图片,Base64编码后变成约133KB。对于大图,这个额外开销是显著的。因此,一般建议只对小于4KB的小图标使用Base64内联。
Base64的常见应用场景
- Data URL:将小图片嵌入CSS或HTML,减少HTTP请求
- HTTP Basic Auth:Authorization: Basic base64(user:pass)
- JWT:JWT的Header和Payload使用Base64Url编码
- 邮件附件:MIME协议要求文本传输,附件必须Base64编码
- LocalStorage:存储二进制数据(虽然不推荐)
Base64Url变体
标准Base64中的+和/在URL中是特殊字符,会被编码。Base64Url用减号替代加号、下划线替代斜杠,并省略等号填充,使其可以直接用在URL参数中。JWT就使用Base64Url编码。
// 标准Base64转Base64Url
function toBase64Url(base64) {
return base64
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
// Base64Url转标准Base64
function fromBase64Url(base64url) {
let base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');
while (base64.length % 4) base64 += '=';
return base64;
}
性能与安全注意事项
Base64编码/解码是CPU密集型操作。对于大文件,同步的atob/btoa可能阻塞主线程。Web Worker可以处理大文件的编码解码而不影响UI。
安全方面,牢记:Base64不是加密。任何人都能解码Base64数据。不要用它来"保护"密码或敏感信息。如果需要安全传输,应该使用HTTPS加真正的加密算法(如AES)。
📅 2026-06-15 · 📖 阅读约10分钟 · 🏷️ 安全, 前端, XSS
开发者安全指南:如何在前端处理敏感数据
前端安全的基本原则
前端代码对用户完全透明——任何人都能通过浏览器开发者工具查看你的JavaScript代码、网络请求和本地存储。这是前端安全的根本约束:不要在前端存放任何不能公开的信息。
这意味着API密钥、数据库密码、加密密钥等敏感信息不应该出现在前端代码中。即使你做了混淆(obfuscation),有决心的攻击者也能还原。
XSS防御:前端安全的第一战线
跨站脚本攻击(XSS)是前端最常见也最危险的安全漏洞。攻击者通过注入恶意脚本,可以窃取用户Cookie、劫持会话、甚至发起钓鱼攻击。
XSS防御的核心原则:永远不信任用户输入。在将任何用户提供的数据插入DOM之前,必须进行转义或清理。
// ❌ 危险:直接插入用户输入
element.innerHTML = userInput;
document.write(userInput);
// ✅ 安全:使用textContent
element.textContent = userInput;
// ✅ 安全:使用DOM API
const text = document.createTextNode(userInput);
element.appendChild(text);
// ✅ 安全:如需插入HTML,使用DOMPurify
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);
Cookie安全配置
Cookie是前端存储敏感令牌(如session ID)的常见方式。正确配置Cookie属性可以大幅提升安全性:
- HttpOnly:禁止JavaScript访问Cookie,防止XSS窃取
- Secure:只在HTTPS连接中发送Cookie
- SameSite=Strict:防止CSRF攻击,不随跨站请求发送Cookie
- Max-Age:设置合理的过期时间
// 服务端设置安全Cookie
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Strict; Max-Age=3600
敏感数据处理最佳实践
- 使用HTTPS:所有包含敏感数据的通信必须使用HTTPS
- 最小权限:前端只获取必要的数据,不要一次性获取所有用户信息
- 自动清除:敏感数据(如信用卡号)在页面关闭后应立即清除
- 避免日志:不要在console.log中输出敏感数据
- CSP策略:配置Content-Security-Policy限制可执行的脚本来源
Content Security Policy (CSP)
CSP是浏览器提供的安全层,通过HTTP头定义哪些来源的脚本、样式、图片等资源可以被加载。即使存在XSS漏洞,CSP也能阻止恶意脚本执行。
// 推荐的CSP配置
Content-Security-Policy:
default-src 'self';
script-src 'self' https://cdn.example.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
connect-src 'self' https://api.example.com;
frame-ancestors 'none';
配置CSP时需要逐步收紧策略。先用report-only模式收集违规报告,确认无误后再启用强制模式。过严的CSP可能导致正常功能异常。
前端存储安全对比
不同存储方式有不同的安全特性:
- Cookie (HttpOnly):JavaScript不可访问,最安全的令牌存储方式
- Session Storage:标签页关闭即清除,但XSS可以访问
- Local Storage:永久存储,XSS可以访问,不适合存敏感数据
- IndexedDB:大容量存储,XSS同样可以访问
结论:如果令牌可以被XSS窃取,那存储在哪里都不安全。真正的解决方案是修复XSS漏洞加上使用HttpOnly Cookie。
安全检查清单
- 所有用户输入在输出时是否经过转义?
- 是否使用了CSP策略?
- Cookie是否设置了HttpOnly、Secure、SameSite?
- 是否在HTTPS下运行?
- 第三方脚本是否来自可信来源?
- 是否在控制台输出了敏感信息?
- 依赖库是否有已知安全漏洞?(使用npm audit检查)
- 是否定期进行安全审计?