有一次我给一个香港的朋友分享我的博客链接。他打开后说:”你网站标题怎么是乱码?”

我当时一愣——我本地看明明好好的。远程一看,首页标题显示了一堆奇奇怪怪的符号。

查了半天才找到原因:服务器的 Content-Type 响应头写死了 charset=gb2312,而我的页面用的却是 UTF-8 编码保存的。浏览器跟着服务器的指示走,解码方式对不上,中文就变成了”天书”。

一句话理解: 字符编码就是”计算机里的 0 和 1 翻译成文字的那本字典”——如果编辑器用一种字典写,浏览器用另一种字典读,出来的就是乱码。

为什么有这么多编码?

这要从计算机的历史说起。

计算机是美国发明的,所以最早的字符编码 ASCII 只考虑了英文——26 个字母加一些符号,128 个位置就够了。但轮到中国、日本、韩国这些国家用计算机时发现——我们那几千个汉字往哪儿放?

于是各国都搞了自己的编码标准:

编码 时间 支持范围 编码容量
GB2312 1980 年 简体中文 6763 个汉字
GBK 1995 年 简体 + 繁体中文 21886 个字符
GB18030 2000 年 简繁 + 少数民族文字 27484 个汉字
Big5 1984 年 繁体中文(港台) 13053 个汉字
UTF-8 1993 年 全世界所有文字 140000+ 个字符

“中文站就用 GB 编码”——这个建议过时了

十年前,确实有人建议:如果你的网站主要面向中国用户,用 GB2312 或 GBK 编码,因为文件体积更小。

这个建议在 2026 年已经完全不适用了。 原因很简单:

  1. UTF-8 已经成为事实标准。所有操作系统、浏览器、编辑器、API 都默认支持 UTF-8。用 GB 编码反而可能遇到兼容性问题——就像我朋友遇到的那样。

  2. 文件体积差距可以忽略。一个 10KB 的 HTML 文件,用 GBK 编码大约 8KB,用 UTF-8 大约 10KB——这点差距在现在的带宽环境下完全可以忽略。

  3. 多语言支持不可替代。如果你的网站有任何外文内容(英文术语、日文品牌名、网友评论里的特殊字符),GB2312 就直接”罢工”了。

1
2
<!-- 2026 年正确的做法:一句搞定 -->
<meta charset="utf-8">

就这一句,放在 <head> 的最前面。

GB2312 → GBK → GB18030:一路扩大的国产编码

如果你需要处理老系统或者历史数据,还是要了解这三者的关系:

  • GB2312:最早的国标,收录 6763 个常用汉字,只支持简体中文
  • GBK:在 GB2312 基础上扩展,增加了繁体中文,共 21886 个字符
  • GB18030:最新的国标,支持简繁 + 藏文、蒙文、维吾尔文等少数民族文字,共 70000+ 字符

它们的兼容关系很简单:GB18030 兼容 GBK,GBK 兼容 GB2312。好比大箱子套小箱子。

经验之谈: 我手上有一个客户的老系统,数据库用的是 GBK 编码,但页面声明的是 UTF-8。每次从数据库读中文都会出现乱码,需要在后端做一次 iconv("GBK", "UTF-8", $text) 转换。这就是历史债务——早期选编码图省事,后面用时间还。

Unicode 和 UTF-8 到底是什么关系?

很多人搞混这两个概念,这里一句话说清楚:

Unicode 是”字符集”(给每个字符一个唯一的编号),UTF-8 是”存储方案”(把这些编号存成字节)。

Unicode 给所有已知文字体系中的每个字符分配了一个唯一的”码点”(code point),比如”中”字的码点是 U+4E2D

而 UTF-8、UTF-16、UTF-32 都是这个码点的”序列化方式”:

方式 英文字符字节数 中文字符字节数 特点
UTF-8 1 字节 3 字节 兼容 ASCII,Web 最常用
UTF-16 2 字节 2 字节 Windows 和 Java 内部使用
UTF-32 4 字节 4 字节 固定长度,空间浪费

UTF-8 赢得了 Web 编码战争——因为它向后兼容 ASCII,纯英文的页面用 UTF-8 和用 ASCII 编码完全一样。2026 年超过 98% 的网站都使用 UTF-8。

容易踩的坑:BOM

BOM(Byte Order Mark)是 UTF-16 时代的产物,在文件开头用几个字节标明字节序。但有些 Windows 编辑器(比如记事本)会在 UTF-8 文件的开头也加上 BOM(EF BB BF),这会造成一个问题:

1
2
3
<!-- 浏览器在解析时,BOM 可能被当作内容显示 -->
<!DOCTYPE html>
<!-- ↑ 开头可能有不可见字符 -->

我的处理建议很简单:所有 Web 文件都保存为”无 BOM 的 UTF-8”

关于 BOM 相关问题,我在网页头部隐藏字符的解决文章里有更详细的讨论。

2026 年的终极建议

编码这件事,在 2026 年已经没什么好纠结的了:

  1. 所有新项目用 UTF-8,不存在任何使用 GB 编码的理由
  2. 老项目遇到乱码,优先检查 meta charset 和服务器 Content-Type 是否一致
  3. 数据库用 utf8mb4(MySQL)或者 UTF-8(PostgreSQL)
  4. 编辑器保存为”无 BOM”格式
1
2
3
4
5
6
# Linux 下检查文件编码
file -i mypage.html
# 输出:mypage.html: text/html; charset=utf-8

# 转换 GBK → UTF-8 的命令
iconv -f GBK -t UTF-8 input.txt > output.txt

相关推荐

P.S. 写完这篇文章后我特意检查了一下自己的博客配置——确认了所有页面都是 UTF-8 编码、服务器响应头正确、没有 BOM。然后我给那位香港朋友发了条消息让他再试试。他说:”能看了。”这句”能看了”大概是我那天听到最舒心的话了。