在浏览器中确定用户区域设置的最佳方法

The*_*o.T 175 javascript browser flash localization

我有一个本地化为十几种语言的网站(Flash),我想根据用户的浏览器设置自动定义默认值,以便最大限度地减少访问内容的步骤.

仅供参考,由于代理限制,我无法使用服务器脚本,因此我猜JavaScript或ActionScript适合解决问题.

问题:

  1. 什么是"猜测"用户的语言环境的最佳方法?

  2. 是否有任何现有的简单类/功能可以帮助我(没有复杂的本地化捆绑)?特别是以智能方式将所有可能的语言分解为较小的数字(我有的翻译).

  3. 我可以相信这样的解决方案?

  4. 还有其他解决方法或建议吗?

bob*_*nce 174

正确的方法是查看发送到服务器的HTTP Accept-Language标头.这包含用户已将其浏览器配置为首选的语言的有序加权列表.

很遗憾,此标头无法在JavaScript中读取; 所有你得到的navigator.language,它告诉你安装了什么本地化版本的Web浏览器.这不一定与用户的首选语言相同.在IE上你得到systemLanguage(操作系统安装的语言),browserLanguage(相同language)和userLanguage(用户配置的操作系统区域),这些都是同样无益的.

如果我有这些属性之间做出选择,我会嗅探userLanguage第一,回落到language只有经过(如果这些不匹配任何可用的语言),看着browserLanguage最后systemLanguage.

如果您可以在网络上的其他位置放置一个服务器端脚本,它只读取Accept-Language标头并将其作为JavaScript文件返回,并带有字符串中的标头值,例如:

var acceptLanguage= 'en-gb,en;q=0.7,de;q=0.3';
Run Code Online (Sandbox Code Playgroud)

然后你可以在HTML中包含指向该外部服务的<script src>,并使用JavaScript来解析语言标题.但是,我不知道有任何现有的库代码可以执行此操作,因为Accept-Language解析几乎总是在服务器端完成.

无论你最终做什么,你当然需要一个用户覆盖,因为它总是会猜错一些人.通常最简单的方法是将语言设置放在URL中(例如,http://www.example.com/en/site vs http://www.example.com/de/site),然后让用户点击两者之间的联系.有时您确实需要两个语言版本的单个URL,在这种情况下,您必须将设置存储在cookie中,但这可能会使用户代理混淆不支持cookie和搜索引擎.

  • 更新:现在(2020)有一个所有现代浏览器都支持的实验性功能,它返回一组语言首选项:`navigator.languages //["en-US", "zh-CN", "ja-JP"]`到 2020 年,这应该可以在至少 95% 的浏览器上运行。 (14认同)
  • @bora89 因为接受的答案是 2009 年,即 13 年前。您知道,实施和文档往往会在这段时间内发生变化...... (9认同)
  • 来自MDN https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/languages"来自用户浏览器的每个HTTP请求中的Accept-Language HTTP标头对navigator.languages属性使用相同的值除了额外的qvalues(质量值)字段(例如en-US; q = 0.8)." (8认同)
  • `navigator.languages`,根据 [MDN](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/languages) 和 [caniuse.com](https://caniuse. com/#feat=mdn-api_navigatorlanguage_languages),现在可在所有主要浏览器中使用 - 尝试使用小型(约 200 字节)[navigator-languages](https://www.npmjs.com/package/navigator-languages) 包最现代且向后兼容的方法。 (5认同)

Fia*_*eid 69

在Chrome和Firefox 32+上,navigator.languages按照用户偏好的顺序包含一系列语言环境,并且比navigator.language更准确,但要使其向后兼容(经过测试的Chrome/IE/Firefox/Safari),然后使用这个:

function getLang()
{
 if (navigator.languages != undefined) 
 return navigator.languages[0]; 
 else 
 return navigator.language;
}
Run Code Online (Sandbox Code Playgroud)

  • 另外,*correct*"one-liner"看起来像这样:`return(navigator.languages && navigator.languages.length)?navigator.languages [0]:navigator.language;`.否则,如果`navigator.languages`未定义或为空,则会出现异常. (20认同)
  • @ChStark不应该是`return navigator.languages [0] || navigator.language;`? (3认同)
  • 对于更紧凑的版本 `const getLang = () =&gt; navigator.language || navigator.browserLanguage || ( navigator.languages || [ "en" ] ) [ 0 ]` (3认同)
  • 这不适用于IE9和IE10.对于他们来说,你必须检查navigator.browserLanguage. (2认同)
  • OneLiner:`function getLang(){return(navigator.language || navigator.languages [0]); }` (2认同)

Phi*_*l H 40

本文建议浏览器导航器对象的以下属性:

  • navigator.language(Netscape - 浏览器本地化)
  • navigator.browserLanguage(IE-Specific - 浏览器本地化语言)
  • navigator.systemLanguage(IE-Specific - Windows操作系统 - 本地化语言)
  • navigator.userLanguage

将这些转换为javascript函数,您应该能够在大多数情况下猜出正确的语言.一定要优雅地降级,所以有一个div包含你的语言选择链接,这样如果没有javascript或方法不起作用,用户仍然可以决定.如果它确实有效,只需隐藏div.

在客户端执行此操作的唯一问题是,您要么将所有语言提供给客户端,要么必须等到脚本运行并在请求正确版本之前检测到语言.也许提供最流行的语言版本作为默认会激怒最少的人.

编辑:我是第二个Ivan的cookie建议,但请确保用户以后可以随时更改语言; 不是每个人都喜欢他们的浏览器默认的语言.


Zen*_*noo 27

结合浏览器用于存储用户语言的多种方式,您可以获得以下功能:

const getNavigatorLanguage = () => {
  if (navigator.languages && navigator.languages.length) {
    return navigator.languages[0];
  } else {
    return navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en';
  }
}
Run Code Online (Sandbox Code Playgroud)

我们首先检查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';
Run Code Online (Sandbox Code Playgroud)

  • `(navigator.languages || [])[0] || navigator.userLanguage || 导航器. 语言 || navigator.browserLanguage || '恩'` (2认同)

Cai*_*tos 17

我使用了所有答案并创建了一个单行解决方案:

const getLanguage = () => navigator.userLanguage || (navigator.languages && navigator.languages.length && navigator.languages[0]) || navigator.language || navigator.browserLanguage || navigator.systemLanguage || 'en';

console.log(getLanguage());
Run Code Online (Sandbox Code Playgroud)


小智 16

用户的首选语言和系统/浏览器区域设置之间存在差异。

用户可以在浏览器中配置首选语言,这些将用于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 实例,然后读回这些已解析选项的语言环境。

  • 添加到图片中的非常重要的答案。例如,在我的 Chromium 中,“navigator.language”给出了 de-DE(这是我的系统设置),但是所有日期和数字的格式都是 en-US(这是我的浏览器设置),这个答案正确地确定了这一点。 (3认同)

Abh*_*k V 5

我对此进行了一些研究,并在下表中总结了到目前为止的发现。

在此处输入图片说明

因此,推荐的解决方案是编写一个服务器端脚本来解析Accept-Language标头,并将其传递给客户端以设置网站的语言。奇怪的是,为什么需要服务器来检测客户端的语言首选项,但是到目前为止就是这样。还有其他各种可用于检测语言的技巧,但是Accept-Language根据我的理解,阅读标头是推荐的解决方案。