如何在浏览器中确定用户的语言环境?

IT技术 javascript flash browser localization
2021-01-14 04:06:36

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

仅供参考,由于代理限制,我无法使用服务器脚本,所以我猜 JavaScript 或 ActionScript 适合解决这个问题。

问题:

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

  2. 是否有任何现有的简单类/函数可以帮助我(没有复杂的本地化包)?特别是以聪明的方式将所有可能的语言减少到较小的数量(我拥有的翻译)。

  3. 在哪一点上我可以相信这样的解决方案?

  4. 任何其他解决方法或建议?

6个回答

正确的方法是查看发送到服务器的 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';

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

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

navigator.languages根据MDNcaniuse.com 的说法,现在可在所有主要浏览器中使用 - 尝试使用微型(~200 字节)navigator-languages包以获得最现代和向后兼容的方法。
2021-03-14 04:06:36
更新:现在(2020 年)有一项所有现代浏览器都支持的实验性功能,该功能会返回一系列语言首选项:navigator.languages //["en-US", "zh-CN", "ja-JP"]到 2020 年,这应该适用于至少 95% 的浏览器。
2021-03-15 04:06:36
来自 MDN developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/... “来自用户浏览器的每个 HTTP 请求中的 Accept-Language HTTP 标头对 navigator.languages 属性使用相同的值,除了额外的qvalues(质量值)字段(例如 en-US;q=0.8)。”
2021-03-27 04:06:36

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

function getLang() {
  if (navigator.languages != undefined) 
    return navigator.languages[0]; 
  return navigator.language;
}
这不适用于 IE9 和 IE10。对于他们,您必须改为检查 navigator.browserLanguage。
2021-03-14 04:06:36
此外,正确“的一行”是这样的:return (navigator.languages && navigator.languages.length) ? navigator.languages[0] : navigator.language;否则,如果navigator.languages未定义或为空,则会出现异常
2021-03-21 04:06:36
对于更紧凑的版本 const getLang = () => navigator.language || navigator.browserLanguage || ( navigator.languages || [ "en" ] ) [ 0 ]
2021-03-28 04:06:36
@ChStark 不应该return navigator.languages[0] || navigator.language;吗?
2021-04-04 04:06:36
单线: function getLang(){ return ( navigator.language || navigator.languages[0] ); }
2021-04-07 04:06:36

本文建议浏览器的navigator对象的以下属性

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

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

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

编辑:我第二个 Ivan 的 cookie 建议,但确保用户以后可以随时更改语言;并非每个人都喜欢浏览器默认使用的语言。

我怀疑现代浏览器都支持 navigator.language。我的浏览器(Ubuntu 8.10 上的 FF3)报告“en-GB”。如果有人仍在使用 IE6 - 大约 20% 的人 - 那么允许这样做是值得的。IE6 出现在 8 年前。
2021-03-13 04:06:36
IE 8 不支持 navigator.language。也许 IE 9 会?
2021-03-22 04:06:36
感谢菲尔的建议。关于这篇文章,它已经有 6 年的历史了……不确定我们可以依靠它吗?
2021-04-09 04:06:36

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

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';
为什么不简单navigator.languages[0] || navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en'
2021-03-22 04:06:36
@Curse 因为navigator.languages可以undefined
2021-03-27 04:06:36
(navigator.languages || [])[0] || navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en'
2021-03-28 04:06:36
@Zenoo 你知道在哪些浏览器上?
2021-03-31 04:06:36
显然也有一些东西navigator.userLanguage(对于IE)。您可以添加它以使其完整:)
2021-04-04 04:06:36

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

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