开发者博客

前端技术教程、开发者工具指南与最佳实践

JSON完全指南:从入门到最佳实践

什么是JSON?

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,由Douglas Crockford在2000年代初期推广。它基于JavaScript对象语法,但已被所有主流编程语言支持。JSON的设计哲学是简单、可读、易于解析,使其成为Web API事实上的标准数据格式。

JSON支持6种数据类型:字符串(必须用双引号)、数字(整数或浮点数)、布尔值(true/false)、null对象(键值对集合)和数组(有序列表)。这种简洁的类型系统足以表达绝大多数数据结构。

JSON语法规则

JSON的语法规则看似简单,但严格程度超出很多人预期:

这些严格规则意味着你不能把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响应时,遵循一致的规范可以大幅提升开发效率:

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仍然是最通用和最安全的选择。

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的常见应用场景

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)。

开发者安全指南:如何在前端处理敏感数据

前端安全的基本原则

前端代码对用户完全透明——任何人都能通过浏览器开发者工具查看你的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属性可以大幅提升安全性:

// 服务端设置安全Cookie
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Strict; Max-Age=3600

敏感数据处理最佳实践

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可能导致正常功能异常。

前端存储安全对比

不同存储方式有不同的安全特性:

结论:如果令牌可以被XSS窃取,那存储在哪里都不安全。真正的解决方案是修复XSS漏洞加上使用HttpOnly Cookie。

安全检查清单

  1. 所有用户输入在输出时是否经过转义?
  2. 是否使用了CSP策略?
  3. Cookie是否设置了HttpOnly、Secure、SameSite?
  4. 是否在HTTPS下运行?
  5. 第三方脚本是否来自可信来源?
  6. 是否在控制台输出了敏感信息?
  7. 依赖库是否有已知安全漏洞?(使用npm audit检查)
  8. 是否定期进行安全审计?