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

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

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

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

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

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

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

656074 次浏览

navigator.userLanguage for IE

window.navigator.language for firefox/opera/safari

我找不到一个单一的引用,说明不涉及服务器端是可能的。

MSDN上:

从browserLanguage:

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

在Internet Explorer 5及以上版本中, 然而,browserLanguage属性 反映操作的语言 系统无论安装 Internet Explorer的语言版本。 但是,如果微软Windows 2000 安装多语言版本, browserLanguage属性所指示的 操作中设置的语言 系统的当前菜单和对话框,如 的区域选项 控制面板。例如,如果你 安装日文版的互联网 探索者5在一个英语(联合 Kingdom)操作系统, browserLanguage将是en-gb。如果你 安装Windows 2000 MultiLanguage 版本,并设置语言 菜单和对话框改为法语, browserLanguage将是fr,甚至 虽然你有日本版的 Internet Explorer。< / p >

注意:此属性不表示 控件设置的一种或多种语言 在“语言首选项”中查找

.单击“Internet选项”

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

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

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

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

它们所影响的是HTTP 'Accept-Language'报头,但似乎这个值在javascript中根本不可用。(可能是为什么@anddoutoi说他找不到一个不涉及服务器端的参考。)

我已经编写了一个解决方案:我已经在http://ajaxhttpheaders.appspot.com上敲出了一个谷歌应用程序引擎脚本,它将通过JSONP返回你的HTTP请求头。

(注意:这是一个黑客,只有当你没有一个可用的后端,可以为你这样做。一般来说,你不应该在你的页面中调用第三方托管的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' =英语美国,等等。


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

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

对于这个问题,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');
为了它的价值,维基媒体的通用语言选择器库有钩子来做这个: https://www.mediawiki.org/wiki/Extension:UniversalLanguageSelector < / p >

参见resources/js/ext.ul .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 < / p >

它仍然取决于服务器,或者更具体地说,取决于MediaWiki API。我展示它的原因是,它可以提供一个很好的示例,用于获取关于用户语言的所有有用信息:浏览器语言、Accept-Language、地理位置(从CLDR获取国家/语言信息),当然还有用户自己的站点首选项。

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>

2014年更新。

现在有一种方法可以在Firefox和Chrome中使用< a href = " https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage.languages " > navigator.languages < / >来获得Accept-Languages(适用于Chrome >= 32和Firefox >= 32)

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

所以,尽可能获得最受欢迎的内容语言,并使用UI语言作为后备:

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

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

navigator.languages

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

到目前为止(2014年9月),这适用于: 铬(v37), Firefox (v32)和 歌剧(v24) < / p >

But not on: IE (v11) < / p >

如果你控制了一个后端并且使用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)

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

基于这里的答案访问web页面's HTTP头在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();
}

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

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);
}
我遇到了这段代码来检测浏览器的语言在Angular翻译模块,你可以找到源在这里。我稍微修改了代码,替换了angular。isArray with 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());

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应用程序/扩展,请使用铬。i18n API

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

我也遇到了同样的问题,于是我编写了以下前端专用库,它为多种浏览器打包了代码。代码并不多,但不用在多个网站上复制和粘贴相同的代码。

Get it: acceptedlanguages.js

使用它:

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

它总是返回一个数组,按用户偏好排序。在Safari &IE数组总是单长度的。在FF和Chrome中,它可能不止一种语言。

如果你使用的是ASP . net MVC,你想从JavaScript中获得Accepted-Languages头,那么这里有一个不涉及任何异步请求的变通例子。

在你的.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服务器解决方案的人

这里是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 : "."}
}
}

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

这对测试也有帮助。

根据客户的不同,您可能不需要这些设置。

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


console.log(language);

  • https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/languages < a href = " https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/languages " > < / >
  • https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/language < a href = " https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/language " > < / >

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

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

把网站的文件放到子目录中。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,并在条件中使用它来可靠地识别首选语言。

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

我刚想到这个。它结合了较新的JS解构语法和一些标准操作来检索语言和区域设置。

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

希望它能帮助到别人

我想分享我的代码,因为它的工作,它是不同于其他给出的答案。 在这个例子中,如果你说法语(法国,比利时或其他法语语言),你将被重定向到法语页面,否则重定向到英语页面,这取决于浏览器配置:

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

我一直在使用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]];
//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在某些属性未定义时出错。增加了跳过这些属性的检查。