[英]How does JavaScript “Date” object determine the locale of the user's browser?
[英]How to determine user's locale within browser?
我有一個本地化為十幾種語言的網站 (Flash),我想根據用戶的瀏覽器設置自動定義默認值,以最大程度地減少訪問內容的步驟。
僅供參考,由於代理限制,我無法使用服務器腳本,所以我想 JavaScript 或 ActionScript 適合解決問題。
問題:
“猜測”用戶語言環境的最佳方法是什么?
是否有任何現有的簡單類/函數可以幫助我(沒有復雜的本地化包)? 特別是以一種聰明的方式將所有可能的語言減少到更小的數量(我有的翻譯)。
我可以信任這樣的解決方案到什么程度?
還有其他解決方法或建議嗎?
正確的方法是查看發送到服務器的 HTTP Accept-Language header。 這包含用戶已將其瀏覽器配置為首選語言的有序加權列表。
不幸的是,此 header 無法在 JavaScript 內讀取; 你得到的只是navigator.language
,它告訴你安裝了 web 瀏覽器的本地化版本。 這不一定與用戶的首選語言相同。 在 IE 上,您會得到systemLanguage
(操作系統安裝的語言)、 browserLanguage
(與language
相同)和userLanguage
(用戶配置的操作系統區域),這些都同樣沒有幫助。
如果我必須在這些屬性之間進行選擇,我會先嗅探userLanguage
,然后回到language
,然后(如果那些不匹配任何可用的語言)查看browserLanguage
最后systemLanguage
。
如果您可以將服務器端腳本放在網絡上的其他地方,該腳本只需讀取 Accept-Language header 並將其作為 JavaScript 文件吐出,其中 Z099FB995346F31C749F6E40DB0F 中的值是 Z099FB995346F31C749F6E40DB03。
var acceptLanguage= 'en-gb,en;q=0.7,de;q=0.3';
那么您可以在 HTML 中包含一個指向該外部服務的 <script src>,並使用 JavaScript 來解析語言 header。 不過,我不知道任何現有的庫代碼可以做到這一點,因為接受語言解析幾乎總是在服務器端完成。
無論你最終做什么,你肯定需要一個用戶覆蓋,因為它總是會猜錯某些人。 通常將語言設置放在 URL 中是最簡單的(例如 http://www.example.com/en/site vs http 和讓用戶點擊com/de/site之間的鏈接)。他們倆。 有時您確實需要一個 URL 用於兩種語言版本,在這種情況下,您必須將設置存儲在 cookies 中,但這可能會使不支持 cookies 的用戶代理混淆。
在 Chrome 和 Firefox 32+ 上, navigator.languages
包含按用戶偏好順序排列的語言環境數組,並且比navigator.language
更准確,但是,為了使其向后兼容(經過測試的 Chrome / IE / Firefox / Safari),然后用這個:
function getLang() {
if (navigator.languages != undefined)
return navigator.languages[0];
return navigator.language;
}
本文建議瀏覽器導航器 object 的以下屬性:
navigator.language
(Netscape - 瀏覽器本地化)navigator.browserLanguage
(IE 特定 - 瀏覽器本地化語言)navigator.systemLanguage
(特定於 IE - Windows OS - 本地化語言)navigator.userLanguage
將這些滾動到 javascript function 中,在大多數情況下,您應該能夠猜出正確的語言。 一定要優雅地降級,所以要有一個包含你的語言選擇鏈接的div,這樣如果沒有javascript或者方法不起作用,用戶仍然可以決定。 如果它確實有效,只需隱藏 div。
在客戶端執行此操作的唯一問題是,您要么向客戶端提供所有語言,要么必須等到腳本運行並檢測到語言才能請求正確的版本。 也許默認提供最流行的語言版本會激怒最少的人。
編輯:我同意 Ivan 的 cookie 建議,但要確保用戶以后可以隨時更改語言; 不是每個人都喜歡他們的瀏覽器默認使用的語言。
結合瀏覽器用來存儲用戶語言的多種方式,你會得到這個 function:
const getNavigatorLanguage = () => {
if (navigator.languages && navigator.languages.length) {
return navigator.languages[0];
} else {
return navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en';
}
}
我們首先檢查navigator.languages
數組的第一個元素。
然后我們得到navigator.userLanguage
或navigator.language
。
如果失敗,我們會得到navigator.browserLanguage
。
最后,如果其他一切都失敗了,我們將其設置為'en'
。
這是性感的單線:
const getNavigatorLanguage = () => (navigator.languages && navigator.languages.length) ? navigator.languages[0] : navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en';
我使用了所有答案並創建了一個單行解決方案:
const getLanguage = () => navigator.userLanguage || (navigator.languages && navigator.languages.length && navigator.languages[0]) || navigator.language || navigator.browserLanguage || navigator.systemLanguage || 'en';
console.log(getLanguage());
用戶的首選語言和系統/瀏覽器區域設置之間存在差異。
用戶可以在瀏覽器中配置首選語言,這些將用於navigator.language(s)
,並在從服務器請求資源時使用,以根據語言優先級列表請求內容。
但是,瀏覽器區域設置將決定如何呈現數字、日期、時間和貨幣。 此設置可能是排名最高的語言,但不能保證。 在 Mac 和 Linux 上,區域設置由系統決定,與用戶語言首選項無關。 在 Windows 上,可以在 Chrome 的首選列表中選擇語言。
通過使用 Intl ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl ),開發人員可以覆蓋/設置用於渲染這些東西的語言環境,但是有些元素不能被覆蓋,例如<input type="date">
格式。
要正確提取這種語言,我發現的唯一方法是:
(new Intl.NumberFormat()).resolvedOptions().locale
( Intl.NumberFormat().resolvedOptions().locale
似乎也有效)
這將為默認語言環境創建一個新的 NumberFormat 實例,然后讀回這些已解析選項的語言環境。
您也可以嘗試從文檔中獲取語言,這可能是您的第一個停靠港,然后回退到其他方式,因為人們通常希望他們的 JS 語言與文檔語言相匹配。
HTML5:
document.querySelector('html').getAttribute('lang')
遺產:
document.querySelector('meta[http-equiv=content-language]').getAttribute('content')
沒有真正的來源一定是 100% 可靠的,因為人們可以簡單地輸入錯誤的語言。
有一些語言檢測庫可以讓您按內容確定語言。
您說您的網站有 Flash,然后,作為另一種選擇,您可以使用flash.system.Capabilities.language
獲取操作系統的語言 - 請參閱如何在瀏覽器中確定操作系統語言以猜測操作系統區域設置。
https://stackoverflow.com/a/42649975/1548557
我剛想到這個。 它結合了較新的 JS 解構語法和一些標准操作來檢索語言和語言環境。
var [lang, locale] = (
(
(
navigator.userLanguage || navigator.language
).replace(
'-', '_'
)
).toLowerCase()
).split('_');
希望它能幫助別人
**更新:** 我還建議對此進行測試並結合其他答案,例如https://stackoverflow.com/a/52112155/1548557 ,這似乎是一種更可靠的獲取語言的方法。 我們還有 null 合並??
所以也許||
不是最好的方法。 我想這就像
var [lang, locale] = (
(
getBrowserLanguage()
.replace('-', '_')
).toLowerCase()
).split('_');
請注意,我沒有強制要求 lang 或 locale 的默認值,您可以這樣做。 這個世界是如此以英語為中心,我會為此選擇英語,但我不覺得它會對我編碼的任何人有好處。我也沒有調用getBrowserLanguage
getNavigatorLanguage
,這是故意的。 也許您使用導航器,但將來可能會出現其他東西。 這確實是一種偏好。 無論如何,我希望這仍然有用。
您可以使用 http 或 https。
https://ip2c.org/XXX.XXX.XXX.XXX或https://ip2c.org/?ip=XXX.XXX.XXX.XXX |
https://ip2c.org/s或https://ip2c.org/self或https://ip2c.org/?self |
一班輪:(支持IE)
var locale = navigator.languages.length ? navigator.languages[0] : (navigator.language || navigator.browserLanguage);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.