這個亂碼問題,生涯罕見!
前兩天我們的 AI 網站用戶反饋了一個亂碼問題
圖片
正常的情況應該如下
圖片
乍一看還是很奇怪的,因為上線之后大多數人是沒有問題的,結果突然間出了這么一例。亂碼問題,無非就是編解碼不一致導致的,那為什么大多數機型的編解碼一致,而少部分卻不一致呢,接下來就是排查階段。
我首先看了下我們項目中的編碼設置
圖片
乍一看沒啥問題,指定的編碼確實是UTF-8,理論上只要在這里指定 UTF-8 編碼,瀏覽器就能據此正常解碼,但為什么這個用戶還是有亂碼問題呢
眼尖的朋友朋友估計一眼就發現了問題,上面的這些配置是配在 root.tsx, 它是一個 tsx 文件,最終是會被編譯成 js 的,也就是說上面的配置是在一個 js 文件中動態生成的!
由于 meta 這些標簽是 js 動態生成的,那么瀏覽器下載拿到 js 文件時其實是不知道它用的是什么編碼的,等你生成了 meta 標簽,它已經解碼完成了,我們可以通過查看一下網頁的源碼驗證一下我們的猜想:
圖片
可以看到源文件中確實沒有 meta utf-8,與我們的猜想相符。
問題找到了但怎么解決呢。主要有兩種方法
- 寫一個模板,讓 vite 編譯時根據這個模板編譯生成帶有 <head><meta charset="UTF-8"></head> 這個選項的源文件,如下
圖片
- 當然了你也可以編譯后寫個腳本將編譯生成的 index.html 文件加上如上標簽
- 還有一種更簡單的方式
之前是因為編譯出的 index.html 缺少 meta 這個標簽,導致瀏覽器無法知道文件用的是什么編碼,那除了這個還有其他辦法讓瀏覽器知道用的是什么編碼嗎,有的,在返回的文件中指定 Content-Type 的 charset 為 utf-8 即可,如下
圖片
我們的工程是 node 工程,請求會先打到 nginx, 再轉發到 node,最終也是通過 nginx 返回的,所以我們在 nginx 的配置文件中設置如下:
圖片
這樣就會在 Content-Type 中返回 charset=utf-8,解碼也就正常了
文中其實留了一個問題,為什么最開始既沒指定 meta 標簽也沒在返回的 header 中指定 Content-Type 但大多數機型卻依然展示正常呢
- 智能字符編碼檢測:現代瀏覽器和操作系統通常具有更強大和精準的字符編碼檢測機制。即使沒有明確指定字符集,它們也能更準確地猜測和識別文本的編碼,尤其是對于常見的編碼格式如 UTF-8。
- 默認編碼假設:許多現代瀏覽器和操作系統可能默認假設文本是 UTF-8 編碼的,特別是當無法從內容中明確識別編碼時。由于 UTF-8 是目前最廣泛使用的字符編碼,這種假設在大多數情況下是有效的。
- 自動字符集轉換:一些現代瀏覽器可能在后臺自動進行字符集轉換,當它們檢測到可能的編碼問題時,會嘗試使用不同的編碼來解析文本,以找到最佳顯示方式。
- 操作系統和瀏覽器更新:隨著操作系統和瀏覽器的更新,對于國際化和多語言支持的改進也在不斷進行。這包括對不同字符編碼的更好支持,使得即使在缺乏明確編碼聲明的情況下,也能正確顯示文本。
- 優化的默認設置:在新版本的操作系統和瀏覽器中,開發者可能已經優化了默認設置,以更好地處理全球化的網絡內容,其中包括對 UTF-8 編碼的優化支持。
然而,即使在最新的系統和瀏覽器中通常能夠正確處理未明確指定字符集的情況,最佳實踐仍然是在服務器端顯式聲明字符集或在 meta 標簽中指定 UTF-8 編碼。這樣可以提供更可靠的用戶體驗,確保在各種環境和設備上的內容都能被正確地顯示,減少因字符編碼問題導致的潛在亂碼問題。