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

我一直在尝试使用JavaScript来检测浏览器语言首选项。

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

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

使用navigator.userLanguage ,它通过Start>ControlPanel>RegionalandLanguageOptions>Regional Options卡检测设置。

我已经用navigator.browserLanguagenavigator.systemLanguage进行了testing,但是都没有返回第一个设置的值( Tools>InternetOptions>General>Languages

我find了一个链接 ,详细讨论这个问题,但问题仍然没有答案:(

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

他们的影响是HTTP'Accept-Language'标题,但是看起来这个值根本不可用。 (可能为什么@anddoutoi说他无法find一个不涉及服务器端的参考。)

我已经编写了一个解决方法:我在http://ajaxhttpheaders.appspot.com上打开了一个Google应用程序引擎脚本,它将通过JSONP返回HTTP请求标头。;

(注意:这只是一个黑客,如果你没有可用的后台可用,一般情况下,你不应该打电话给页面中的第三方托pipe的JavaScript文件,除非你有很高的对主机的信任程度。)

我打算永远把它留在那里,所以随时在你的代码中使用它。

以下是一些示例代码(在jQuery中),以便您如何使用它

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

希望有人认为这有用。

编辑:我写了一个小的jQuery插件github包装这个function: 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() 

编辑3:有开源的应用程序引擎代码在这里: 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' =英语美国等。


正如rcoupWebMacheter在下面评论中所指出的那样,这个解决方法不会让用户在IE浏览器以外的浏览器中查看网站时,在英文方言之间进行区分。

window.navigator.language (Chrome / FF / Safari)总是返回浏览器语言,而不是浏览器的首选语言,但是:“英语用户(gb,au,nz等)拥有Firefox / Chrome浏览器/ Safari浏览器“。 因此,即使用户首选语言是en-GB window.navigator.language仍然会返回en-US

2014年更新。

现在有一种方法可以使用navigator.languages (在Chrome> = 32和Firefox> = 32中工作)在Firefox和Chrome中获得Accept-Languages,

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

所以,如果可能的话获得最喜欢的内容语言,并使用UI语言作为后备:

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

我碰到这段代码来检测浏览器在Angular Translate模块中的语言,你可以在这里find源代码。 我稍微修改了代码,用Array.isArrayreplaceangular.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()); 
 <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> 

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

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

有没有体面的方式来获得设置,至less不是浏览器独立的东西。

但是服务器有这个信息,因为它是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

navigator.userLanguage为IE

window.navigator.language for firefox / opera / safari

Javascript方式:

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

如果你使用jQuery.i18n插件 ,你可以使用:

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

我找不到一个单独的参考,说明有可能不涉及服务器端。

在MSDN上:

  • 航海家。 浏览器语言
  • 航海家。 SYSTEMLANGUAGE
  • 航海家。 使用者语言

从browserLanguage:

在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不列出它

如果您正在开发Chrome App / Extension,请使用chrome.i18n API 。

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

DanSingerman对这个问题有一个非常好的解决scheme。

该语言的唯一可靠来源是HTTP请求头。 所以你需要一个服务器端脚本来回复请求头或者至lessAccept-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'); 

维基媒体的通用语言select库有这样的function: 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获取国家/语言信息),当然,用户自己的网站偏好。

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

 navigator.languages 

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

截至目前(2014年9月),Chrome(v37),Firefox(v32)和Opera(v24)

但不是:IE(v11)

我有同样的问题,我写了下面的前端唯一的库,包装多个浏览器的代码。 这不是太多的代码,但很高兴不需要复制和粘贴相同的代码跨多个网站。

得到它: acceptedlanguages.js

用它:

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

它总是返回一个数组,按用户首选项sorting。 在Safari和IE中,数组总是单个长度。 在FF和Chrome中,它可能不止一种语言。

Dan Singerman的回答有一个问题,就是由于jQuery的ajax的asynchronous特性,所获取的头文件必须马上使用。 然而,在他的谷歌应用程序服务器,我写了以下内容,使标题设置为初始设置的一部分,并可以在以后使用。

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

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

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

希望它可以帮助别人

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

我的更新(如下)将返回第一个长格式代码,例如“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]]; len = language.length; if (!shortLanguage && len) { shortLanguage = language; } if (language && len > 2) { return language; } } return shortLanguage; } console.log(getFirstBrowserLanguage()); 

首先,请原谅我的英语。 我想分享我的代码,因为它的工作原理与给出的其他代码不同。 在这个例子中,如果您讲法语(法语,比利时语或其他法语),您将在法语页面上redirect,否则在英语页面上,取决于浏览器configuration:

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

如果你有一个后端的控制权,并使用Django,丹的思想的四行实现是:

 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头我build立了以下脚本来获取浏览器语言:

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

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

如果您正在使用ASP .NET MVC,并且您想从JavaScript获取Accepted-Languages标头,那么这是一个解决scheme示例,不包含任何asynchronous请求。

在.cshtml文件中,将头部安全地存储在div的data-attribute中:

 <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解决scheme

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

我有一个不同的方法,这可能有助于未来的人:

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

所以我设置一个初始设置取决于configuration设置(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 : "."} } } 

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

这对于testing的目的也应该是有帮助的。

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

我有一个黑客,我认为使用很less的代码,是相当可靠的。

把你的网站的文件放在一个子目录中。 SSL到您的服务器,并创build符号链接到您的文件存储,指示您的语言的子目录。

像这样的东西:

 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,并根据它提供的语言值redirect到这些“不同的子目录”。

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

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