用于检测浏览器语言偏好的 JavaScript

IT技术 javascript localization internationalization
2021-01-26 02:55:45

我一直在尝试使用 JavaScript 检测浏览器语言偏好。

如果我在 IE 中设置浏览器语言Tools>Internet Options>General>Languages,如何使用 JavaScript 读取该值?

Firefox 也有同样的问题。我无法检测到tools>options>content>languages使用的设置navigator.language

使用 navigator.userLanguage ,它会检测通过Start>ControlPanel>RegionalandLanguageOptions>Regional Options选项卡完成的设置

我已经测试过navigator.browserLanguagenavigator.systemLanguage但都没有返回第一个设置的值(Tools>InternetOptions>General>Languages

我找到了一个详细讨论此问题链接,但问题仍未得到解答:(

6个回答

我认为这里的主要问题是浏览器设置实际上并不影响navigator.language通过 javascript 获取属性。

它们确实影响的是 HTTP 'Accept-Language' 标头,但该值似乎根本无法通过 javascript 获得。(可能是为什么@anddoutoi 说他找不到不涉及服务器端的参考。)

我编写了一个解决方法:我在http://ajaxhttpheaders.appspot.com编写了一个谷歌应用引擎脚本,它将通过 JSONP 返回 HTTP 请求标头。

(注意:如果您没有可用的后端可以为您执行此操作,则仅可使用此技巧。通常,除非您有非常高的对主机的信任程度。)

我打算将它永久保留在那里,因此请随时在您的代码中使用它。

这是一些示例代码(在 jQuery 中),用于说明如何使用它

$.ajax({ 
    url: "http://ajaxhttpheaders.appspot.com", 
    dataType: 'jsonp', 
    success: function(headers) {
        language = headers['Accept-Language'];
        nowDoSomethingWithIt(language);
    }
});

希望有人觉得这很有用。

编辑:我在 github 上编写了一个包含此功能的小型 jQuery 插件:https : //github.com/dansingerman/jQuery-Browser-Language

编辑 2:这里要求的是在 AppEngine 上运行的代码(真的超级简单):

class MainPage(webapp.RequestHandler):
    def get(self):
        headers = self.request.headers
        callback = self.request.get('callback')

        if callback:
          self.response.headers['Content-Type'] = 'application/javascript'
          self.response.out.write(callback + "(")
          self.response.out.write(headers)
          self.response.out.write(")")
        else:
          self.response.headers['Content-Type'] = 'text/plain'
          self.response.out.write("I need a callback=")

application = webapp.WSGIApplication(
                                     [('/', MainPage)],
                                     debug=False)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()

Edit3:在这里开源了应用引擎代码:https : //github.com/dansingerman/app-engine-headers

@deckard ummm - 互联网全球性的。appengine 脚本应该可以在 Internet 上的任何地方正常工作。但是 - 这对于没有可用后端的开发人员来说确实是一个黑客 - 它不应该用于您可以控制后端的“真实”站点。
2021-03-11 02:55:45
@MatthewFlaschen 你说得对(在我的辩护中,我在 2 年前大约 5 分钟内编写了脚本。)我会在有机会时修复它。
2021-03-22 02:55:45
是否有其他可靠的站点像 Google 一样返回 HTTP 请求标头?我想要做的是将用户重定向到他们的浏览器语言设置,我的网站是全球性的。所以我需要依赖全球可用和永久的站点。
2021-03-30 02:55:45
嗨,丹,这个问题有 14k 次观看并且还在增加 - 也许你想在 github 上发布你的脚本?问候,毫秒
2021-04-02 02:55:45
@msec 我已按要求发布了 Python appengine 脚本。请注意,如果服务器端可用,这在任何语言中都应该非常简单 - 该服务实际上只需要为那些没有(或不想拥有)服务器端组件的人提供。
2021-04-04 02:55:45
var language = window.navigator.userLanguage || window.navigator.language;
alert(language); //works IE/SAFARI/CHROME/FF

window.navigator.userLanguage仅是 IE,它是在Windows 控制面板 - 区域选项中设置的语言,而不是浏览器语言,但您可以假设使用将 Window 区域设置设置为法国的计算机的用户可能是法国用户。

navigator.language 是 FireFox 和所有其他浏览器。

一些语言代码:'it'=意大利,'en-US'=英语美国等。


正如rcoupThe WebMacheter在下面的评论中指出的那样,当用户在 IE 以外的浏览器中查看网站时,此解决方法不会让您区分英语方言。

window.navigator.language(Chrome/FF/Safari) 总是返回浏览器语言而不是浏览器的首选语言,但是:“对于说英语的人(gb、au、nz 等)来说,拥有 en-us 版本的 Firefox/Chrome/Safari 是很常见的。” 因此window.navigator.language仍然会返回en-US即使用户首选语言en-GB

@stunpix - 也许 Chrome 会自动将键盘布局添加到首选语言。但是您可以编辑此列表并window.navigator.languages从首选项中订购语言列表:chrome://settings/languages
2021-03-17 02:55:45
Chrome 具有window.navigator.languages多种用户首选语言。
2021-03-19 02:55:45
@MarcoDemaio 说英语的人(gb、au、nz 等)拥有 en-us 版本的 Firefox/Chrome/Safari 是很常见的。有时 en-gb 版本存在,但它们并不流行,而且其他 en 变体肯定没有。
2021-03-23 02:55:45
@Anzeo:说一种语言的用户访问您网站的可能性很小,但安装了另一种语言的浏览器,然后他们还设置了另一种首选语言。正如其他人所说,没有像样的方法,我的答案是一个简单的简短解决方法,用于通常不会导致致命错误的任务。如果您必须完全确定用户使用什么语言,您可以随时通过在您的站点上添加一个选择列表并将其选择保存到 cookie 中来询问他。
2021-04-05 02:55:45
这是不正确的。navigator.language在 Chrome 中调用将返回 Chrome 显示的语言,而不是用户的首选语言(这是语言列表顶部的语言)。
2021-04-06 02:55:45

2014 年更新。

现在有一种方法可以使用navigator.languages在 Firefox 和 Chrome 中获取 Accept-Languages (适用于 Chrome >= 32 和 Firefox >= 32)

此外,这些年来 Firefox 中的navigator.language反映了最喜欢的内容语言,而不是 UI 语言。但是由于这个概念还没有被其他浏览器支持,所以它不是很有用。

因此,为了尽可能获得最喜欢的内容语言,并使用 UI 语言作为后备:

navigator.languages
    ? navigator.languages[0]
    : (navigator.language || navigator.userLanguage)
获得语言navigator.languages[0]是个坏主意。我的系统的默认语言是俄语并navigator.language返回正确的语言代码“ru”。navigator.languages返回["en-US", "en", "ru", "uk"]因此,获取索引为 0 的语言将为您提供“en-US”,这对我的系统来说是不正确的。请不要使用 navigator.languages 来检测当前系统的语言。
2021-03-16 02:55:45
@stunpix 不,这不正确。数组中首选语言的顺序反映了用户设置的顺序:developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/...
2021-03-21 02:55:45
@stunpix 这不是关于系统语言,而是关于浏览器内的偏好。这可能与系统语言一致,也可能不一致,具体取决于安装的浏览器。我建议您查看浏览器的设置。Firefox:首选项-内容-语言,Chrome:设置(高级)-语言
2021-03-26 02:55:45
获取首选语言列表或回退到 UI 语言(均作为数组)的替代实现是: window.navigator.languages || [window.navigator.language || window.navigator.userLanguage]
2021-03-31 02:55:45
还有一件事:navigator.languages表示按字母顺序(!)排序的可用于用户系统中文本输入的语言列表。它们不按照用户的偏好排序。
2021-04-09 02:55:45

我在Angular Translate module中遇到了这段代码来检测浏览器的语言,你可以在这里找到源代码我通过用 Array.isArray 替换 angular.isArray 稍微修改了代码,使其独立于 Angular 库。

var getFirstBrowserLanguage = function () {
    var nav = window.navigator,
    browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'],
    i,
    language;

    // support for HTML 5.1 "navigator.languages"
    if (Array.isArray(nav.languages)) {
      for (i = 0; i < nav.languages.length; i++) {
        language = nav.languages[i];
        if (language && language.length) {
          return language;
        }
      }
    }

    // support for other well known properties in browsers
    for (i = 0; i < browserLanguagePropertyKeys.length; i++) {
      language = nav[browserLanguagePropertyKeys[i]];
      if (language && language.length) {
        return language;
      }
    }

    return null;
  };

console.log(getFirstBrowserLanguage());

这似乎比其他 JS 答案更可靠,例如对 language.length 的检查意味着它将跳过语言数组中的空项目(如果发生这种情况?)
2021-03-10 02:55:45
EamonnM 对这段代码的编辑可能更优化,参见:stackoverflow.com/a/46514247/9314312
2021-03-12 02:55:45
要在检测到 nav.languages 是数组时支持旧浏览器,您应该使用: Object.prototype.toString.call(nav.languages) === '[object Array]'
2021-03-28 02:55:45
澄清:旧浏览器 = ( IE <=8.0 )
2021-04-04 02:55:45

let lang = window.navigator.languages ? window.navigator.languages[0] : null;
    lang = lang || window.navigator.language || window.navigator.browserLanguage || window.navigator.userLanguage;

let shortLang = lang;
if (shortLang.indexOf('-') !== -1)
    shortLang = shortLang.split('-')[0];

if (shortLang.indexOf('_') !== -1)
    shortLang = shortLang.split('_')[0];

console.log(lang, shortLang);

我只需要满足我需要的主要组件,但您可以轻松地使用完整的字符串。适用于最新的 Chrome、Firefox、Safari 和 IE10+。