用于检测浏览器语言首选项的JavaScript

时间:2009-06-25 11:08:11

标签: javascript localization internationalization

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

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

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

使用navigator.userLanguage,它会检测完成的设置 Start>ControlPanel>RegionalandLanguageOptions>Regional Options标签。

我已使用navigator.browserLanguagenavigator.systemLanguage进行了测试,但均未返回第一个设置的值(Tools>InternetOptions>General>Languages

我找到了一个link,详细讨论了这一点,但问题仍然没有答案:(

26 个答案:

答案 0 :(得分:276)

答案 1 :(得分:232)

var language = window.navigator.userLanguage || window.navigator.language;
alert(language); //works IE/SAFARI/CHROME/FF

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

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

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


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

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

答案 2 :(得分:193)

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)

答案 3 :(得分:49)

我遇到了这段代码,用于检测Angular Translate module中的浏览器语言,您可以找到源here。我通过将angular.isArray替换为Array.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());

答案 4 :(得分:31)

var language = navigator.languages && navigator.languages[0] || // Chrome / Firefox
               navigator.language ||   // All browsers
               navigator.userLanguage; // IE <= 10

console.log(language);

尝试PWA模板https://github.com/StartPolymer/progressive-web-app-template

答案 5 :(得分:28)

<script type="text/javascript">
var lang = window.navigator.languages ? window.navigator.languages[0] : null;
    lang = lang || window.navigator.language || window.navigator.browserLanguage || window.navigator.userLanguage;
if (lang.indexOf('-') !== -1)
    lang = lang.split('-')[0];

if (lang.indexOf('_') !== -1)
    lang = lang.split('_')[0];
</script>

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

答案 6 :(得分:17)

没有合适的方式来获得该设置,至少不是浏览器独立的。

但服务器具有该信息,因为它是HTTP请求标头的一部分(Accept-Language字段,请参阅http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4

所以唯一可靠的方法是从服务器回复。您需要在服务器上运行的东西(如.asp,.jsp,.php,CGI),并且“thing”可以返回该信息。 这里有很好的例子:http://www.developershome.com/wap/detection/detection.asp?page=readHeader

答案 7 :(得分:15)

IE的

navigator.userLanguage

window.navigator.language for firefox / opera / safari

答案 8 :(得分:10)

我一直在使用Hamid的答案,但是在语言数组就像[&#34; en&#34;,&#34; en-GB&#34; ,&#34; en-US&#34;,&#34; fr-FR&#34;,&#34; fr&#34;,&#34; en-ZA&#34;]它将返回&#34; en&#34;,&#34; en-GB&#34;将是一个更好的匹配。

我的更新(如下)将返回第一个长格式代码,例如&#34; en-GB&#34;,否则它将返回第一个短代码,例如&#34; en&#34;,否则返回null。

&#13;
&#13;
function getFirstBrowserLanguage() {
        var nav = window.navigator,
            browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'],
            i,
            language,
            len,
            shortLanguage = null;

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

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

        return shortLanguage;
    }

console.log(getFirstBrowserLanguage());
&#13;
&#13;
&#13;

答案 9 :(得分:7)

我找不到一个引用,声明可以不涉及服务器端。

MSDN on:

来自browserLanguage:

  

在Microsoft Internet Explorer 4.0和   之前,browserLanguage属性   反映了已安装的语言   浏览器的用户界面。例如,   如果你安装日文版   Windows Internet Explorer上的   英文操作系统,   browserLanguage将是ja。

     

在Internet Explorer 5及更高版本中,   但是,bro​​wserLanguage属性   反映了经营的语言   系统无论安装   Internet Explorer的语言版本。   但是,如果是Microsoft Windows 2000   安装了MultiLanguage版本,   browserLanguage属性表示   操作中设置的语言   系统的当前菜单和对话框,如   发现在区域选项中   控制面板。例如,如果你   安装日语版的Internet   资源管理器5英文(美国)   王国)操作系统,   browserLanguage将是en-gb。如果你   安装Windows 2000 MultiLanguage   版本并设置语言   菜单和对话到法语,   browserLanguage甚至是fr   虽然你有日文版的   Internet Explorer。

     
    

注意此属性不表示     由语言设定的语言     位于语言首选项中的用户     在“Internet选项”对话框中。

  

此外,看起来browserLanguage已被弃用,因为IE8没有列出它

答案 10 :(得分:7)

我刚刚提出这个问题。它结合了较新的JS解构语法和一些标准操作来检索语言和语言环境。

var [lang, locale] = (((navigator.userLanguage || navigator.language).replace('-', '_')).toLowerCase()).split('_');

希望它有助于某人

答案 11 :(得分:7)

我遇到了同样的问题,我编写了以下前端库,它包含了多个浏览器的代码。代码不多,但不必在多个网站上复制和粘贴相同的代码。

获取它:acceptedlanguages.js

使用它:

<script src="acceptedlanguages.js"></script>
<script type="text/javascript">
  console.log('Accepted Languages:  ' + acceptedlanguages.accepted);
</script>

它始终返回一个按用户首选项排序的数组。在Safari&amp; IE数组总是单一长度。在FF和Chrome中,它可能不止一种语言。

答案 12 :(得分:7)

如果您正在开发Chrome应用/扩展程序,请使用chrome.i18n API

chrome.i18n.getAcceptLanguages(function(languages) {
  console.log(languages);
  // ["en-AU", "en", "en-US"]
});

答案 13 :(得分:7)

Javascript方式:

var language = window.navigator.userLanguage || window.navigator.language;//returns value like 'en-us'

如果您使用的是jQuery.i18n plugin,则可以使用:

jQuery.i18n.browserLang();//returns value like '"en-US"'

答案 14 :(得分:6)

如果您只需要支持某些现代浏览器,那么您现在可以使用:

navigator.languages

以用户指定的顺序返回用户语言首选项的数组。

截至目前(2014年9月),这适用于: Chrome(第37版), Firefox(v32)和 歌剧(第24集)

但不是: IE(v11)

答案 15 :(得分:6)

对于它的价值,维基媒体的通用语言选择器库有这样做的钩子: https://www.mediawiki.org/wiki/Extension:UniversalLanguageSelector

请参阅resources / js / ext.uls.init.js中的函数getFrequentLanguageList。直接链接: https://gerrit.wikimedia.org/r/gitweb?p=mediawiki/extensions/UniversalLanguageSelector.git;a=blob;f=resources/js/ext.uls.init.js;hb=HEAD

它仍然取决于服务器,或者更具体地说,取决于MediaWiki API。我展示它的原因是它可以提供一个很好的例子来获取有关用户语言的所有有用信息:浏览器语言,接受语言,地理定位(从CLDR获取国家/语言信息),当然,用户自己的网站偏好。

答案 16 :(得分:6)

DanSingerman对这个问题有很好的解决方案。

该语言唯一可靠的来源是HTTP请求标头。 因此,您需要一个服务器端脚本来回复请求标头或至少回复Accept-Language字段。

这是一个非常简单的Node.js服务器,应该与DanSingermans jQuery插件兼容。

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end(JSON.stringify(req.headers));
}).listen(80,'0.0.0.0');

答案 17 :(得分:2)

Dan Singerman的回答有一个问题,即由于jQuery的ajax的异步特性,必须立即使用提取的标题。但是,通过他的谷歌应用服务器,我编写了以下内容,以便将标题设置为初始设置的一部分,并可以在以后使用。

<html>
<head>
<script>

    var bLocale='raw'; // can be used at any other place

    function processHeaders(headers){
        bLocale=headers['Accept-Language'];
        comma=bLocale.indexOf(',');
        if(comma>0) bLocale=bLocale.substring(0, comma);
    }

</script>

<script src="jquery-1.11.0.js"></script>

<script type="application/javascript" src="http://ajaxhttpheaders.appspot.com?callback=processHeaders"></script>

</head>
<body>

<h1 id="bLocale">Should be the browser locale here</h1>

</body>

<script>

    $("#bLocale").text(bLocale);

</script>
</html>

答案 18 :(得分:2)

首先,请原谅我的英语。 我想分享我的代码,因为它有效,并且它与其他给出的答案不同。 在这个例子中,如果您说法语(法国,比利时或其他法语),您将被重定向到法语页面,否则在英语页面上,具体取决于浏览器配置:

<script type="text/javascript">
        $(document).ready(function () {
            var userLang = navigator.language || navigator.userLanguage;
            if (userLang.startsWith("fr")) {
                    window.location.href = '../fr/index.html';
                }
            else {
                    window.location.href = '../en/index.html';
                }
            });
    </script>

答案 19 :(得分:0)

如果您不想依赖外部服务器并拥有自己的服务器,则可以使用简单的PHP脚本来实现与@DanSingerman回答相同的行为。

<强> languageDetector.php

<?php
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
echo json_encode($lang);
?>

只需从jQuery脚本中更改这一行:

url: "languageDetector.php",
dataType: 'json',
success: function(language) {
    nowDoSomethingWithIt(language);
}

答案 20 :(得分:0)

根据这里的答案Accessing the web page's HTTP Headers in JavaScript,我构建了以下脚本来获取浏览器语言:

var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
var contentLanguage = headers.match( /^content-language\:(.*)$/gm );
if(contentLanguage[0]) {
    return contentLanguage[0].split(":")[1].trim().toUpperCase();
}

答案 21 :(得分:0)

如果您掌握了后端并且正在使用django,那么Dan的想法的4行实现是:

def get_browser_lang(request):
if request.META.has_key('HTTP_ACCEPT_LANGUAGE'):
    return JsonResponse({'response': request.META['HTTP_ACCEPT_LANGUAGE']})
else:
    return JsonResponse({'response': settings.DEFAULT_LANG})

然后在urls.py中:

url(r'^browserlang/$', views.get_browser_lang, name='get_browser_lang'),

并在前端:

$.get(lg('SERVER') + 'browserlang/', function(data){
    var lang_code = data.response.split(',')[0].split(';')[0].split('-')[0];
});

(你必须在settings.py中设置DEFAULT_LANG)

答案 22 :(得分:0)

如果您正在使用ASP .NET MVC并且想要从JavaScript获取 Accepted-Languages 标头,那么这是一个不涉及任何异步请求的变通方法示例。

在.cshtml文件中,将标题安全地存储在div的数据属性中:

<div data-languages="@Json.Encode(HttpContext.Current.Request.UserLanguages)"></div>

然后您的JavaScript代码可以访问该信息,例如使用JQuery:

<script type="text/javascript">
$('[data-languages]').each(function () {
    var languages = $(this).data("languages");
    for (var i = 0; i < languages.length; i++) {
        var regex = /[-;]/;
        console.log(languages[i].split(regex)[0]);
    }
});
</script>

当然,您可以像其他人提到的那样,使用与其他服务器技术类似的方法。

答案 23 :(得分:0)

谁在寻找Java Server解决方案

这是RestEasy

@GET
@Path("/preference-language")
@Consumes({"application/json", "application/xml"})
@Produces({"application/json", "application/xml"})
public Response getUserLanguagePreference(@Context HttpHeaders headers) {
    return Response.status(200)
            .entity(headers.getAcceptableLanguages().get(0))
            .build();
}

答案 24 :(得分:0)

我有一种不同的方法,这可能会对未来的某些人有所帮助:

客户想要一个可以交换语言的页面。 我需要按照该设置格式化数字(不是浏览器设置/不是任何预定义的设置)

所以我根据配置设置(i18n)设置初始设置

$clang = $this->Session->read('Config.language');
echo "<script type='text/javascript'>var clang = '$clang'</script>";

稍后在脚本中我使用了一个函数来确定我需要的数字格式

function getLangsettings(){
  if(typeof clang === 'undefined') clang = navigator.language;
  //console.log(clang);
  switch(clang){
    case 'de':
    case 'de-de':
        return {precision : 2, thousand : ".", decimal : ","}
    case 'en':
    case 'en-gb':
    default:
        return {precision : 2, thousand : ",", decimal : "."}
  }
}

所以我使用了页面的设置语言,作为后备,我使用了浏览器设置。

这也应该有助于测试目的。

取决于您的客户,您可能不需要这些设置。

答案 25 :(得分:0)

我有一个黑客,我认为使用非常少的代码并且非常可靠。

将您网站的文件放在子目录中。 SSL进入您的服务器并创建符号链接到存储文件的子目录,指示您的语言。

这样的事情:

ln -s /var/www/yourhtml /var/www/en
ln -s /var/www/yourhtml /var/www/sp
ln -s /var/www/yourhtml /var/www/it

使用您的网络服务器读取HTTP_ACCEPT_LANGUAGE并重定向到这些&#34;不同的子目录&#34;根据它提供的语言价值。

现在您可以使用Javascript的window.location.href来获取您的网址并在条件中使用它来可靠地识别首选语言。

url_string = window.location.href;
if (url_string = "http://yoursite.com/it/index.html") {
    document.getElementById("page-wrapper").className = "italian";
}