在我給網站添加了按需加載語言的功能壹段時間後,測試給我發現了這樣壹個bug。
也許是因為支持的語言太少,國外用戶太少,所以這個問題才發現的這麽晚。
那我們來看這個問題。
用戶將網站語言設置為中文,但瀏覽器將語言設置為英文。
用戶打開網站,跳轉到登錄界面。因為用戶沒有登錄,前端讀到瀏覽器是英文的,所以動態加載英文。
輸入用戶名和密碼以跳轉到主頁。因為使用了單頁應用程序(SPA ),並且沒有刷新頁面,所以副本仍然是英文的。
用戶需要刷新頁面以獲得他設置的中文版本。
最簡單的解決方法是丟棄不刷新頁面的SPA的“假跳轉”,換成真正的跳轉。
也就是說,不要用React路由器的API,也不要用原來底層是history.pushState()的Vue路由器庫,直接用window.location.href = homeUrl。
登錄請求成功後,前端獲取用戶令牌。然後跳轉到首頁,做壹個重新加載語言的操作,因為有了用戶憑證,我們就可以正確加載用戶設置的語言了。
雖然SPA打包的文件通常很大,但是我們有緩存,所以重新加載是相當快的。
這裏有壹個可選的優化點:如果用戶設置的語言與瀏覽器語言相同,仍然可以使用“假跳轉”。這需要後端合作,以便登錄界面可以額外返回當前用戶語言字段。
請求登錄界面。獲得用戶令牌後,需要獲得用戶設置的語言。
根據這個語言標識,動態獲取對應的語言包JS文件,下載語言包並覆蓋原語言包,然後“假跳轉”到首頁。
同樣,如果用戶的語言與瀏覽器的語言相同,可以直接“假跳”到首頁。
看起來不是很復雜,其實裏面有很多坑。
若要使用此方案,必須確保您的代碼能夠響應語言包對象。也就是說,語言包對象壹改變,妳的組件和方法就得自動改變。
這意味著在某些情況下,不能使用緩存,壹些涉及國際文案的邏輯要用函數的形式來寫。組件不能使用外部靜態內容,需要依賴Context或者Redux,會觸發組件重渲染。
當然,這樣做還有壹個好處,就是在切換語言的時候,不需要重新加載頁面,組件會重新渲染應用新的語言副本。
我更喜歡用方案1,因為它簡單,適合任何場景。另外,千萬不要登錄再登錄,會有很多狀態變化,不容易維護。
此外,註銷還需要重新加載頁面,因為用戶語言和瀏覽器語言可能不同。