簡體   English   中英

如何在瀏覽器中確定用戶的語言環境?

[英]How to determine user's locale within browser?

我有一個本地化為十幾種語言的網站 (Flash),我想根據用戶的瀏覽器設置自動定義默認值,以最大程度地減少訪問內容的步驟。

僅供參考,由於代理限制,我無法使用服務器腳本,所以我想 JavaScript 或 ActionScript 適合解決問題。

問題:

  1. “猜測”用戶語言環境的最佳方法是什么?

  2. 是否有任何現有的簡單類/函數可以幫助我(沒有復雜的本地化包)? 特別是以一種聰明的方式將所有可能的語言減少到更小的數量(我有的翻譯)。

  3. 我可以信任這樣的解決方案到什么程度?

  4. 還有其他解決方法或建議嗎?

正確的方法是查看發送到服務器的 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.userLanguagenavigator.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 實例,然后讀回這些已解析選項的語言環境。

我對此進行了一些研究,並在下表中總結了迄今為止的發現

在此處輸入圖像描述

因此推薦的解決方案是編寫一個服務器端腳本來解析Accept-Language header 並將其傳遞給客戶端以設置網站的語言。 奇怪的是,為什么需要服務器來檢測客戶端的語言偏好,但到目前為止就是這樣。還有其他各種黑客可用於檢測語言,但根據我的理解,閱讀Accept-Language header 是推薦的解決方案。

您也可以嘗試從文檔中獲取語言,這可能是您的第一個停靠港,然后回退到其他方式,因為人們通常希望他們的 JS 語言與文檔語言相匹配。

HTML5:

document.querySelector('html').getAttribute('lang')

遺產:

document.querySelector('meta[http-equiv=content-language]').getAttribute('content')

沒有真正的來源一定是 100% 可靠的,因為人們可以簡單地輸入錯誤的語言。

有一些語言檢測庫可以讓您按內容確定語言。

您說您的網站有 Flash,然后,作為另一種選擇,您可以使用flash.system.Capabilities.language獲取操作系統的語言 - 請參閱如何在瀏覽器中確定操作系統語言猜測操作系統區域設置。

JavaScript 移植這個用於檢測瀏覽器語言偏好

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.XXXhttps://ip2c.org/?ip=XXX.XXX.XXX.XXX |

  • 標准 IPv4 從 0.0.0.0 到 255.255.255.255

https://ip2c.org/shttps://ip2c.org/selfhttps://ip2c.org/?self |

  • 處理調用者的 IP
  • 比?dec= 選項更快,但僅限於一個目的 - 提供有關您自己的信息

參考: https://about.ip2c.org/#inputs

一班輪:(支持IE)

var locale = navigator.languages.length ? navigator.languages[0] : (navigator.language || navigator.browserLanguage);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM