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

2020/09/26 17:01 · javascript ·  · 0评论

我一直在尝试使用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

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

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

它们确实影响的是HTTP'Accept-Language'标头,但看来此值根本无法通过javascript使用。(可能是为什么@anddoutoi指出他找不到不涉及服务器端的引用)。

我已经编码了一种解决方法:我在http://ajaxhttpheaders.appspot.com敲了一个Google应用引擎脚本,脚本将通过JSONP返回HTTP请求标头。

(请注意:这是一种hack,仅当您没有可用的后端可以使用时才能使用。通常,除非您的浏览器具有很高的访问权限,否则不应在页面中调用第三方托管的javascript文件对主机的信任级别。)

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

这是一些使用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

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'=美国英语,等等。


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

window.navigator.language(Chrome / FF / Safari)始终返回浏览器语言,而不返回浏览器的首选语言,但是:“英语使用者(gb,au,nz等)拥有Firefox / Chrome / Safari的在用版本是很常见的。” 因此,即使用户首选的语言是,window.navigator.language也仍然会返回en-USen-GB

2014年更新。

现在,有一种方法可以使用navigator.languages在Firefox和Chrome中获取接受语言 (在Chrome> = 32和Firefox> = 32中有效)

另外,近年来Firefox中的navigator.language反映了内容的首选语言,而不是UI的语言。但是,由于其他浏览器尚未支持此概念,因此它不是很有用。

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

navigator.languages
    ? navigator.languages[0]
    : (navigator.language || navigator.userLanguage)

我在Angular Translate模块中遇到了这段代码来检测浏览器的语言,您可以在此处找到源代码我通过用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());
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 +。

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

navigator.userLanguage 对于IE

window.navigator.language 用于Firefox / Opera / Safari

没有合适的方法来获得该设置,至少不是与浏览器无关。

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

因此,唯一可靠的方法是从服务器获取答案。您将需要在服务器上运行的内容(例如.asp,.jsp,.php,CGI),并且“内容”可以返回该信息。此处的好例子:http : //www.developershome.com/wap/detection/detection.asp?page=readHeader

我一直在使用Hamid的答案,但是在语言数组如[“ en”,“ en-GB”,“ en-US”,“ fr-FR”,“ fr”,“ en -ZA“],当“ en-GB”是一个更好的匹配时,它将返回“ en”。

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

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]];
            //skip this loop iteration if property is null/undefined.  IE11 fix.
            if (language == null) { continue; } 
            len = language.length;
            if (!shortLanguage && len) {
                shortLanguage = language;
            }
            if (language && len > 2) {
                return language;
            }
        }

        return shortLanguage;
    }

console.log(getFirstBrowserLanguage());

更新:未定义某些属性时,IE11错误。添加了检查以跳过这些属性。

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

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

希望对别人有帮助

我找不到一个单独的引用,指出在不涉及服务器端的情况下是可能的。

MSDN上:

从浏览器语言:

在Microsoft Internet Explorer 4.0和更早版本中,browserLanguage属性反映了已安装浏览器用户界面的语言。例如,如果在英语操作系统上安装日语版本的Windows Internet Explorer,则browserLanguage将为ja。

但是,在Internet Explorer 5和更高版本中,无论安装了Internet Explorer的语言版本如何,browserLanguage属性都反映操作系统的语言。但是,如果安装了Microsoft Windows 2000 MultiLanguage版本,则browserLanguage属性指示在操作系统的当前菜单和对话框中设置的语言,可以在“控制面板”的“区域选项”中找到该语言。例如,如果在英语(英国)操作系统上安装日语版的Internet Explorer 5,则browserLanguage将为en-gb。如果您安装Windows 2000 MultiLanguage版本并将菜单和对话框的语言设置为法语,则即使您具有日语版的Internet Explorer,browserLanguage也将是fr。

注意此属性不会指示用户在“ Internet选项”对话框的“语言首选项”中设置的一种或多种语言。

此外,它似乎browserLanguage已被弃用,因为IE8没有列出它

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

navigator.languages

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

截至目前(2014年9月),该功能适用​​于:Chrome(v37),Firefox(v32)和Opera(v24)

但不支持:IE(v11)

Javascript方式:

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

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

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

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

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

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

获得它:acceptedlanguages.js

用它:

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

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

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

该语言的唯一可靠来源是HTTP-request标头。因此,您需要一个服务器端脚本来将请求标头或至少该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');

对于它的价值,Wikimedia的通用语言选择器库具有执行此操作的挂钩: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获取国家/语言信息),当然用户自己的网站偏好设置。

丹·辛格曼(Dan Singerman)的答案有一个问题,由于jQuery的ajax具有异步特性,因此必须立即使用提取的标头。但是,我使用他的google app服务器编写了以下内容,以便将标头设置为初始设置的一部分,并可以在以后使用。

<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>

首先,请原谅我的英语。我想分享我的代码,因为它可以正常工作,并且与其他响应者不同。在此示例中,如果您会讲法语(法国,比利时或其他法语),则将根据法语(在浏览器上的配置)在法语页面上进行重定向,否则在英语页面上进行重定向:

<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>

如果您不想依赖外部服务器,并且拥有自己的服务器,则可以使用简单的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);
}

如果您可以控制后端并使用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)

根据此处的答案,使用JavaScript访问网页的HTTP标头,我构建了以下脚本来获取浏览器语言:

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();
}

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

在您的.cshtml文件中,将标头安全地存储在div的data-属性中:

<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>

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

对于谁在寻找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();
}

我有不同的方法,这可能会在将来对某人有所帮助:

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

所以我根据配置设置(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 : "."}
  }
}

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

对于测试目的也应该有所帮助。

根据您的客户,您可能不需要该设置。

我认为我使用的代码很少,非常可靠。

将站点的文件放在子目录中。通过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

使用您的Web服务器读取HTTP_ACCEPT_LANGUAGE并根据它提供的语言值重定向到这些“不同的子目录”。

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

url_string = window.location.href;
if (url_string = "http://yoursite.com/it/index.html") {
    document.getElementById("page-wrapper").className = "italian";
}
本文地址:http://javascript.askforanswer.com/yongyujianceliulanqiyuyanpianhaodejavascript.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!