网页与接口响应
页面头部声明了一种编码,响应头又声明了另一种,浏览器只能二选一,于是正文先乱后正常。统一由响应头决定,并让页面声明与之保持一致,是最稳妥的处理。
字符集与文本修复专刊
当多语言文本撞上错位编码:从字符现象出发,把网页、数据库与跨平台文件里的乱码一处一处对回来。
亚洲嫩草乱码专栏处理的是一件很具体的事:一段原本正常的文本,在某个环节被按另一套字符集读出来,于是字面还在、意思散了。它可能发生在网页响应头与页面声明不一致的时候,也可能发生在数据库连接串、导出的 CSV、跨系统同步的日志文件里。
同一个汉字,用 UTF-8 写、用 GBK 读,会变成两个毫不相干的高位字符;用 Big5 写、用 GB18030 读,常常出现成对的怪字与问号;而日文假名进入简体中文环境,则更容易变成连续的方块或替换符。把这些痕迹分门别类,修复就变成了对号入座。
本刊的做法是先看现象,再定编码,最后改动最靠前的那一环。改动位置越靠前,需要善后的地方越少——这是多年整理文本问题时最省力的一条经验。
| 看到的痕迹 | 常见成因 |
|---|---|
| 丠一类成对拉丁扩展字符 | UTF-8 字节被按 Latin-1 解读 |
| 连续的方块、问号或替换符 | 目标字符集缺字,无法映射 |
| 汉字成串但语义完全不对 | 同为双字节方案,如 GBK 与 Big5 互读 |
| 只有部分段落异常,其余正常 | 同一页面混用了两种编码来源 |
| 数据库里正常、页面上异常 | 连接层字符集与存储层不一致 |
先把痕迹抄下来,连同出现的位置一起记录。痕迹本身就是线索,比反复猜测可靠得多。
亚洲语系里最常打交道的四套方案,各有自己的字节节奏。知道它们的边界在哪里,就能判断该往哪个方向回退。
| 方案 | 字节特征 | 互读时的典型表现 |
|---|---|---|
| UTF-8 | 变长,1–4 字节,兼容 ASCII | 被单字节方案读时,出现成对的拉丁扩展字符 |
| GBK / GB18030 | 双字节为主,高位字节区间固定 | 与 Big5 互读,得到成串意义不明的汉字 |
| Big5 | 双字节,覆盖繁体字集 | 进入简体环境常出现空缺与替代符号 |
| Shift_JIS | 双字节,假名区独立 | 在中文环境下多成方块或连续问号 |
判断顺序建议固定下来:先确认文件真实的字节编码,再确认读取端声明的编码,最后才动手转换。跳过前两步直接转码,往往把可恢复的文本变成不可恢复。
一套流程只解决一处问题。同站点之间的问题往往同源,改完一处后顺手检查同类页面,能省下大量重复劳动。
页面头部声明了一种编码,响应头又声明了另一种,浏览器只能二选一,于是正文先乱后正常。统一由响应头决定,并让页面声明与之保持一致,是最稳妥的处理。
存储层是变长编码,连接层却是单字节方案,写入时正常、读出时错位。检查连接参数、字段排序规则与导出文件格式,三处一起看,避免只改一环。
在简体环境生成的文件送到繁体或日文环境打开,常出现部分行正常、部分行错乱。给文件加一份说明性的同目录备注,或统一以变长编码落盘,可以显著减少此类问题。
把编码当作一项基础设定来管理:新项目一律使用变长编码;旧系统改造时先盘点数据源,再定统一出口;转换前备份原始字节,转换后抽样校验首尾段落。
对于来源不一的外部文本,先落到中间层做一次统一转换,再进入正式库表。中间层多花的一点时间,通常远少于事后逐条修复的成本。