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