meta charset:UTF-8 沒設好,中文搜尋結果就變亂碼
charset 是 檔頭標籤 裡唯一有 位置硬性要求 的一個,也是中文網站唯一「設錯就整頁報廢」的設定。
<meta charset="UTF-8">慣例是放在 <head> 的第一行。規格要求的其實是「完整出現在前 1024 個位元組內」,而放第一行是最省事、也最不會出錯的滿足方式。
為什麼必須放最前面
規格要求:完整出現在前 1024 個位元組內
瀏覽器接到 HTML 時是 一邊下載一邊解析 的。要把位元組還原成文字,它必須先知道編碼。
所以規格規定編碼宣告要完整出現在檔案的 前 1024 個位元組 內。找不到宣告,瀏覽器就改用猜的(依語言環境、內容特徵推測);如果猜錯了又在後面讀到宣告,就得 丟掉重新解析,中文可能因此先閃一次亂碼。
正確的檔頭開頭:
<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>頁面標題</title>
<!-- 其餘標籤 -->
</head>
</html>2
3
4
5
6
7
8
9
這樣會超過限制
把大段的 ld+json 或內嵌樣式放在 charset 前面,很容易一口氣吃掉 1024 個位元組:
<head>
<script type="application/ld+json">
{
/* 幾百行的結構化資料 */
}
</script>
<meta charset="UTF-8">
<!-- 太晚了 -->
</head>2
3
4
5
6
7
8
9
UTF-8 還是 Big5
| UTF-8 | Big5 | |
|---|---|---|
| 涵蓋範圍 | 全世界的文字與表情符號 | 一萬多個繁體漢字 |
| 缺字問題 | 幾乎沒有 | 嚴重(罕用字、異體字) |
| 混用其他語言 | 可以 | 不行 |
| 現代工具支援 | 全面 | 需要額外處理 |
| 建議 | 一律用這個 | 只在維護舊系統時 |
新專案沒有理由不用 UTF-8
Big5 連「堃」、「喆」這類姓名常用字都可能缺,也無法同時呈現簡體字、日文或表情符號。維護舊系統若必須沿用,至少要確保 宣告與實際存檔編碼一致,不一致才是亂碼的真正來源。
亂碼對 SEO 的實際後果
亂碼不是「看起來醜」而已,它讓整頁對搜尋引擎失去意義:
| 位置 | 後果 |
|---|---|
<title> | 搜尋結果的標題是亂碼,沒人會點 |
description | 摘要是亂碼 |
| 內文 | 搜尋引擎無法判斷主題,也對不上任何中文搜尋字詞 |
| Open Graph | 社群分享的預覽卡片同樣亂碼 |
| 結構化資料 | 標記內容無效 |
等於這一頁 沒有內容。這也是為什麼它被列在 技術 SEO 檢查清單 的必備項目。
三個地方要一致
亂碼的成因幾乎都是「宣告的編碼」與「實際的編碼」不一致。要對齊三個地方:
| 位置 | 怎麼設 |
|---|---|
| 檔案存檔編碼 | 編輯器設成 UTF-8(不帶 BOM) |
| HTTP 回應標頭 | Content-Type: text/html; charset=utf-8 |
| HTML 宣告 | <meta charset="UTF-8"> |
HTTP 標頭的優先權更高
若標頭指定的編碼與頁面裡的宣告不一致,瀏覽器會 採用標頭的版本。所以「我明明寫了 UTF-8 卻還是亂碼」的情況,常常是伺服器回傳了別的編碼。
用開發者工具的網路面板看回應標頭就能確認。
不要用 BOM
BOM(Byte Order Mark)是檔案開頭的三個位元組,用來標示編碼。在 HTML 裡通常無害,但:
- 寫在伺服器端腳本開頭時,可能造成輸出多出不可見字元、影響回應標頭。
- 寫在 CSS 開頭時,部分解析器會忽略第一條規則。
- 版本控制的 diff 會多出看不見的差異。
統一使用不帶 BOM 的 UTF-8 最單純。編輯器通常標示為「UTF-8」對應不帶 BOM,「UTF-8 with BOM」則要避免。
別忘了 lang 屬性
charset 管的是「位元組怎麼變成文字」,lang 管的是「這是什麼語言」。兩者不同但都該設:
<html lang="zh-Hant-TW"></html>lang 影響螢幕閱讀器的發音、瀏覽器的翻譯提示與斷行規則。多語系網站還要搭配 hreflang ,語言代碼的寫法在那一篇說明。
檢查清單
| 項目 | 標準 |
|---|---|
有 <meta charset="UTF-8"> | 必備 |
它是 <head> 的第一行 | 必備 |
| 檔案存檔為 UTF-8(不帶 BOM) | 必備 |
| HTTP 標頭的編碼與宣告一致 | 必備 |
<html> 有 lang 屬性 | 建議 |
怎麼快速驗證
直接開網頁看中文正不正常就好,這是唯一「一眼就能驗完」的 SEO 檢查。
常見問題
為什麼 charset 一定要放在最前面?
規格要求它必須完整出現在檔案的前 1024 個位元組內。瀏覽器在讀到宣告之前就已經開始解析位元組,找不到宣告就得改用猜的;若猜錯再重新解析,中文就可能先閃一次亂碼。
還需要用 Big5 嗎?
不需要,新專案一律用 UTF-8。Big5 只涵蓋一萬多個漢字,缺字問題嚴重,也無法同時呈現簡體、日文或表情符號。維護舊系統時若必須沿用,至少要確保宣告與實際存檔編碼一致。
亂碼對 SEO 的實際影響是什麼?
搜尋引擎讀到的標題與內文全是亂碼,無法判斷這一頁在講什麼,也無法對應到任何中文搜尋字詞。搜尋結果會直接顯示亂碼,社群分享的預覽卡片同樣如此,等於這一頁沒有內容。
HTTP 標頭和 meta 標籤哪個優先?
HTTP 回應標頭的優先權更高。若標頭指定的編碼與頁面裡的宣告不一致,瀏覽器會採用標頭的版本。兩邊都設定並保持一致最保險,只設 meta 標籤在多數情況下也夠用。
檔案要不要存成帶 BOM 的 UTF-8?
不要。BOM 是檔案開頭的三個位元組,在 HTML 裡通常無害,但寫在伺服器端腳本或 CSS 開頭時可能造成輸出多出空白字元、影響回應標頭。統一使用不帶 BOM 的 UTF-8 最單純。