有站長遇到過這样的情况:後台編輯器里顯示正常,前台打開却是一串問号、方块,或者“锟斤拷”“且這類看不懂的字符。這類問题往往不在文案本身,而在字符编碼的某一段鏈路上,文件存的是什么编碼、資料库存的是什么编碼、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 輸出,头部编碼声明是否與實际輸出一致。
- 在後台發布一篇带标点、數字、生僻字和表情符号的測試文章,從錄入到前台顯示走一遍完整流程。
五、统一改動时注意顺序
如果確認是歷史遗留的编碼不统一,改動前先备份資料库和站点文件。轉換编碼尽量一次性完成,不要只改前台不改後台,也不要只改資料库不改连接配置,否則容易出現“新資料正常、老資料乱碼”的混合狀態。改完之後,用前面那份清單再走一遍,確認各類頁面都能正常顯示,再观察一段時間站点的抓取和展示情况是否稳定。
编碼這類問题平时不起眼,一旦出現却會影响訪客阅讀和内容抓取。把它当成站点运营里的常規自查項,比事後逐個頁面去猜要省事得多。