JavaScript字符串与Base64互转需用btoa/atob,但处理中文须先通过TextEncoder转UTF-8字节再编码,Base64还原时用TextDecoder解码;URL传输需做安全替换,Node.js中应使用Buffer。

JavaScript 中字符串的编码与解码,核心在于区分「字符串内容本身」和「传输/存储时的字节表示」。JS 的 String 类型内部使用 UTF-16 编码,但实际开发中常需与 UTF-8 字节流(如 URL、API 请求体、localStorage)交互,这时必须显式编码/解码,否则容易出现乱码或数据损坏。
URL 中的编码与解码:用 encodeURIComponent 和 decodeURIComponent
URL 只允许 ASCII 字符,中文、emoji 或特殊符号(如空格、`/`、`?`)必须转义。直接拼接未编码的字符串会导致 URL 解析错误或服务端接收异常。
-
编码:用
encodeURIComponent(),它对除字母、数字及部分安全字符(- _ . ! ~ * ' ( ))外的所有字符进行 UTF-8 编码后百分号转义,例如:encodeURIComponent('你好')→%E4%BD%A0%E5%A5%BD -
解码:用
decodeURIComponent()还原,注意若输入非法转义序列(如%GG),会抛出URIError - 不要用
encodeURI()处理完整 URL,它不编码/ ? : @ & = + $ , #等保留字符,仅适合编码路径片段或查询值
UTF-8 字节流与字符串互转:借助 TextEncoder / TextDecoder
当需要将字符串存入 ArrayBuffer、发送二进制请求(如 fetch 的 body: Uint8Array)、或处理 Base64 编码数据时,必须在 UTF-16 字符串与 UTF-8 字节之间转换。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
-
字符串 → UTF-8 字节:
const uint8 = new TextEncoder().encode('?abc')→Uint8Array(6) [0xF9, 0x9D, 0x9C, 0x61, 0x62, 0x63](注意:Unicode 超过 U+FFFF 的字符如「?」占 4 字节) -
UTF-8 字节 → 字符串:
new TextDecoder().decode(uint8)→'?abc',默认使用 UTF-8,也可指定其他编码(如ISO-8859-1,但兼容性有限) - 这两个 API 是现代标准,IE 不支持,需考虑 polyfill 或降级方案(如使用第三方库
encoding-japanese处理 Shift-JIS)
Base64 编解码:btoa/atob 的局限与替代方案
btoa() 和 atob() 仅支持 Latin-1(单字节)字符串,直接传入中文会报错 DOMException: The string to be encoded contains characters outside of the Latin1 range。
立即学习“Java免费学习笔记(深入)”;
- 正确做法:先用
TextEncoder将字符串转为 UTF-8 字节,再用Uint8Array转为 base64(可借助Buffer.from(bytes).toString('base64')在 Node.js;浏览器可用Array.from(bytes, byte => String.fromCodePoint(byte)).join('')配合btoa—— 但更推荐统一用TextEncoder + base64-arraybuffer类库) - 现代推荐:使用
Buffer.from(str, 'utf8').toString('base64')(Node.js)或浏览器中const bytes = new TextEncoder().encode(str); const bin = String.fromCharCode(...bytes); btoa(bin)(仅适用于较短字符串,避免栈溢出) - 解码时反向操作:先
atob()得到 Latin-1 字符串,再用TextDecoder解码为原始字符串
JSON 与 localStorage 中的编码问题
JSON.stringify() 默认将非 ASCII 字符转为 \uXXXX 形式(UTF-16 代码点转义),这是合法且安全的,无需额外处理;localStorage 存储的是 DOMString,本质是 UTF-16,也天然支持中文等字符。
- 但要注意:若手动拼接 JSON 字符串或用正则替换,可能破坏转义格式,导致解析失败
- 如果后端要求纯 UTF-8 字节形式的 JSON(如某些嵌入式设备接口),需先
JSON.stringify(),再用TextEncoder编码为字节,而非直接传字符串 - localStorage 的 value 是字符串,不是字节,所以
localStorage.setItem('data', '中文')完全正常,不必 encodeURI

















