有站长遇到过这样的情况:后台编辑器里显示正常,前台打开却是一串问号、方块,或者“锟斤拷”“且这类看不懂的字符。这类问题往往不在文案本身,而在字符编码的某一段链路上,文件存的是什么编码、数据库存的是什么编码、HTTP 头声明的是什么编码,只要有一处不一致,中文就可能变形。
一、先判断乱码出现在哪一层
不要一看到乱码就去改数据库,先定位问题发生在哪一步,改起来才不会越改越乱。
- 看页面源码:在浏览器里查看源代码,如果源码里就是乱码,问题出在数据库或模板输出阶段。
- 看响应头:用 curl -I 或浏览器开发者工具的 Network 面板,看 Content-Type 里有没有带 charset,带的是不是 utf-8。
- 看 meta 声明:检查 HTML 源码 head 里的 meta charset,和响应头是否一致。
- 看后台表单:如果只有从后台提交的内容乱码,而静态页面正常,问题多半在数据库连接字符集或表单提交编码。
二、三处声明最好保持一致
比较稳妥的做法是全站统一用 UTF-8,并且三处声明都对得上:
- HTTP 响应头:返回 Content-Type: text/html; charset=utf-8。这一层的优先级通常高于页面内的 meta 声明,所以不能只改 meta 不管服务端。
- HTML meta:把 meta charset="utf-8" 放在 head 的最前面,尽量靠前出现,避免浏览器在读到声明之前就按默认编码解析了一段内容。
- 数据库与连接:库、表、字段以及连接字符集统一为 utf8mb4。如果站内需要支持表情符号或部分生僻字,用 utf8mb4 会比早期的三字节 utf8 更省事。
文件本身也要保存为 UTF-8,并且留意 BOM。带 BOM 的文件有时会在页面顶部多出不可见字符,轻则多一段空白,重则影响页面头部输出,排查时容易被忽略。
三、html lang 声明别一直留着默认值
很多模板默认写的是 lang="en",套用中文站之后一直没改。这个属性主要影响屏幕阅读器的发音、浏览器的翻译提示,也会给搜索引擎一个语种参考。
- 简体中文页面一般写 lang="zh-CN",繁体页面可以写 zh-Hant 或对应地区代码。
- 如果站点有简繁或多语言版本,除了各自的 lang 声明,还可以用 hreflang 标注不同语言版本的对应关系。
- 页面中夹了一段英文原文引用时,可以给那段内容单独加 lang,但不必整页来回切换。
四、可以直接照做的自查清单
- 抽查首页、栏目页、文章页、搜索页、404 页,看响应头里的 charset 是否都是 utf-8。
- 确认 meta charset 出现在 head 靠前的位置,而不是被一堆脚本和样式挤到后面。
- 检查模板里的 html lang 是否已经改成对应语种。
- 查看数据库、表和字段的字符集,并确认程序连接时也指定了同样的字符集。
- 检查 RSS、站点地图等 XML 输出,头部编码声明是否与实际输出一致。
- 在后台发布一篇带标点、数字、生僻字和表情符号的测试文章,从录入到前台显示走一遍完整流程。
五、统一改动时注意顺序
如果确认是历史遗留的编码不统一,改动前先备份数据库和站点文件。转换编码尽量一次性完成,不要只改前台不改后台,也不要只改数据库不改连接配置,否则容易出现“新数据正常、老数据乱码”的混合状态。改完之后,用前面那份清单再走一遍,确认各类页面都能正常显示,再观察一段时间站点的抓取和展示情况是否稳定。
编码这类问题平时不起眼,一旦出现却会影响访客阅读和内容抓取。把它当成站点运营里的常规自查项,比事后逐个页面去猜要省事得多。