很多站点在做内容时,栏目名、文章标题、图片文件名直接用了中文,系統自動生成的 URL 也就带着一長串百分号编碼。對訪客来说還能点得進去,對搜尋蜘蛛来说,却可能出現「同一個頁面好几個地址」「連結抓過去 404」「日誌里成片抓取失敗」這些問题。這篇從编碼角度梳理一下,哪些位置容易出错,可以怎么统一。
编碼本身没有错,問题出在不统一
URL 規范里,非 ASCII 字符需要先按某種字符集编碼,再寫成百分号形式。中文「中」在 UTF-8 下是 %E4%B8%AD,在 GBK 下是 %D6%D0。两種寫法在浏览器里看起来都能打開同一個頁面,但對搜尋蜘蛛来说,這就是两條不同的 URL。如果站点里一部分連結走 UTF-8、一部分走 GBK,或者前後端用了不同的编碼函數,同一篇内容就會被拆成多個入口,外鏈、内鏈、分享連結各自指向不同版本,權重自然被分散。
容易出問题的几個位置
- 中文栏目名、中文文章 slug,尤其是編輯在後台手填标题就直接生成地址的站点。
- 空格的處理方式不一致:有的是 %20,有的是 +,有的被替換成连字符,三種寫法同时存在。
- 半角全角符号混用,括号、书名号、顿号、中点等符号在编碼後長度不同,容易出現断鏈。
- 文件名里带了 #、?、& 這類保留字符,编碼後语义被截断,蜘蛛拿到的地址和實际资源對不上。
- 大小寫不统一的编碼,例如 %2f 與 %2F,在部分服務器上被当作不同路径。
- 站内搜尋關鍵詞直接落到 URL 上,用戶搜一次生成一批新地址,抓取预算被大量消耗。
常见的错誤寫法
一個典型场景是老站点改版:早期用 GBK 生成的連結還挂在別的站点的外鏈里,新站按 UTF-8 生成地址,两邊指向同一篇内容。蜘蛛顺着外鏈抓到舊地址,服務器返回 200,頁面照常顯示,于是舊地址也被收錄,和新的規范地址打架。另一種场景是前端用 encodeURI、後端自己拼字符串,两個函數對保留字符的處理規則不一样,同一個标题在两處生成出不同的地址。
可以落地的處理思路
- 優先使用英文或拼音 slug,把中文标题保留在 title 和 H1 里。地址短、無编碼、便于人手動輸入,是最省事的方案。
- 如果业務上必须保留中文 URL,就全站统一按 UTF-8 编碼,並確認服務器能正确解碼,不要混用字符集。
- 把 URL 生成收敛到一個函數里,前端、後端、模板都調它,避免同一标题生成多個版本。
- 空格统一用连字符 -,不要用 + 或 %20。
- slug 里剔除 #、?、&、/ 等保留字符,用连字符替代。
- 對已经存在的舊编碼地址做 301 到規范地址,尽量不要再让两個版本同时返回 200。
- 站内搜尋结果頁加上 noindex,並避免被大量内鏈暴露,减少無意义的抓取。
顺手做一次日誌自查
打開服務器日誌,篩選带 % 的請求行,大致能看到三件事:有多少编碼 URL 被频繁抓取;這些請求的响應碼是 200 還是 404;同一條路径是否存在多種编碼形式。再抽查几條编碼 URL,看它們的狀態碼、canonical 指向和規范地址是否一致。如果發現同一篇内容有两個都能打開的地址,先把其中一個 301 掉,比事後慢慢等收錄收敛要快。
编碼問题的本质不是「中文 URL 不好」,而是同一個頁面被编碼成了多個地址。先把地址收敛到一條,再谈收錄。
這件事不需要大改架构,多數情况下只是把生成規則统一、把歷史遗留的舊地址重定向一次。花半天時間整理清楚,後面做栏目規划、内容更新时就不用每次都重新踩一遍同样的坑。