J'ai essayé de détecter la préférence de langue du navigateur à l'aide de JavaScript.
Si je règle la langue du navigateur dans IE dans Tools>Internet Options>General>Languages
, comment lire cette valeur à l'aide de JavaScript?
Même problème pour Firefox. Je ne parviens pas à détecter le réglage de tools>options>content>languages
avec navigator.language
.
En utilisant navigator.userLanguage
, il détecte le réglage effectué dans l’onglet Start>ControlPanel>RegionalandLanguageOptions>Regional Options
.
J'ai testé avec navigator.browserLanguage
et navigator.systemLanguage
mais je ne retourne ni la valeur du premier paramètre (Tools>InternetOptions>General>Languages
).
J'ai trouvé un lien qui en discute en détail, mais la question reste sans réponse :(
Je pense que le principal problème ici est que les paramètres du navigateur n’affectent pas la propriété navigator.language
obtenue via javascript.
Ce qu'ils affectent, c'est l'en-tête HTTP 'Accept-Language', mais il semble que cette valeur ne soit pas disponible via JavaScript. (Probablement pourquoi @anddoutoi déclare qu’il ne trouve pas de référence qui n’implique pas le côté serveur.)
J'ai codé une solution de contournement: j'ai créé un script de moteur d'application Google à l'adresse http://ajaxhttpheaders.appspot.com qui vous renverra les en-têtes de requête HTTP via JSONP.
(Remarque: il ne s'agit que d'un hack à utiliser si vous ne disposez pas d'un back-end disponible pouvant le faire pour vous. En général, vous ne devriez pas appeler de fichiers javascript hébergés tiers dans vos pages, sauf si vous avez une niveau de confiance dans l'hôte.)
J'ai l'intention de le laisser là-bas à perpétuité, alors n'hésitez pas à l'utiliser dans votre code.
Voici un exemple de code (en jQuery) pour son utilisation
$.ajax({
url: "http://ajaxhttpheaders.appspot.com",
dataType: 'jsonp',
success: function(headers) {
language = headers['Accept-Language'];
nowDoSomethingWithIt(language);
}
});
J'espère que quelqu'un trouve cela utile.
Edit: J'ai écrit un petit plugin jQuery sur github qui englobe cette fonctionnalité: https://github.com/dansingerman/jQuery-Browser-Language
Edit 2: Comme demandé, voici le code qui tourne sur AppEngine (super trivial):
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 __== "__main__":
main()
Edit3: Open source a obtenu le code du moteur de l'application ici: 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
n'est que IE et c'est la langue définie dans Panneau de configuration Windows - Options régionales et PAS la langue du navigateur, mais vous pouvez supposer qu'un utilisateur utilisant une machine avec Windows Les paramètres régionaux définis en France sont probablement des utilisateurs français.
navigator.language
est FireFox et tous les autres navigateurs.
Quelques codes de langue: 'it'
= italie, 'en-US'
= anglais US, etc.
Comme souligné par rcoup et le WebMacheter dans les commentaires ci-dessous, cette solution de contournement ne vous laissera pas distinguer les dialectes anglais lorsque les utilisateurs consultent des sites Web dans des navigateurs autres que IE.
window.navigator.language
(Chrome/FF/Safari) renvoie toujours la langue du navigateur et non la langue préférée du navigateur, mais: "il est assez courant que les anglophones (gb, au, nz, etc.) avoir une version fr-us de Firefox/Chrome/Safari ". Par conséquent, window.navigator.language
retournera toujours en-US
même si la langue préférée de l'utilisateur est en-GB
.
Mise à jour de l'année 2014.
Il existe maintenant un moyen d'obtenir Accept-Languages dans Firefox et Chrome en utilisant navigator.languages ( fonctionne dans Chrome> = 32 et Firefox> = 32)
En outre, navigator.language dans Firefox ces années reflète la langue de contenu la plus préférée, et non la langue de l'interface utilisateur. Mais comme cette notion n’est pas encore supportée par d’autres navigateurs, elle n’est pas très utile.
Donc, pour obtenir la langue de contenu la plus préférée lorsque possible et utiliser la langue de l'interface utilisateur comme solution de secours:
navigator.languages
? navigator.languages[0]
: (navigator.language || navigator.userLanguage)
Je suis tombé sur ce morceau de code pour détecter la langue du navigateur dans module de traduction angulaire , dont vous pouvez trouver la source ici . J'ai légèrement modifié le code en remplaçant angular.isArray par Array.isArray pour le rendre indépendant de la bibliothèque 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());
var language = navigator.languages && navigator.languages[0] || // Chrome / Firefox
navigator.language || // All browsers
navigator.userLanguage; // IE <= 10
console.log(language);
Essayez le modèle PWA https://github.com/StartPolymer/progressive-web-app-template
<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>
Je n'avais besoin que du composant principal pour mes besoins, mais vous pouvez facilement utiliser la chaîne complète. Fonctionne avec les dernières versions de Chrome, Firefox, Safari et IE10 +.
Il n'y a pas de moyen décent d'obtenir ce paramètre, du moins pas quelque chose d'indépendant du navigateur.
Mais le serveur a cette information, car elle fait partie de l’en-tête de la requête HTTP (le champ Accept-Language, voir http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14). 4 )
Le seul moyen fiable consiste donc à obtenir une réponse du serveur. Vous aurez besoin de quelque chose qui fonctionne sur le serveur (comme .asp, .jsp, .php, CGI) et cette "chose" peut renvoyer cette information. Bons exemples ici: http://www.developershome.com/wap/detection/detection.asp?page=readHeader
navigator.userLanguage
pour IE
window.navigator.language
pour firefox/opera/safari
J'utilise la réponse de Hamid depuis un moment, mais dans les cas où le tableau de langues ressemble à ["en", "en-GB", "en-US", "fr-FR", "fr", "en -ZA "] il retournera" en ", quand" en-GB "serait un meilleur match.
Ma mise à jour (ci-dessous) renverra le premier code long format, par exemple. "en-GB", sinon le premier code abrégé sera retourné, par exemple. "en", sinon il retournera 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());
J'ai eu le même problème et j'ai écrit la bibliothèque suivante uniquement front-end qui enveloppe le code pour plusieurs navigateurs. Ce n'est pas beaucoup de code, mais il est agréable de ne pas avoir à copier et coller le même code sur plusieurs sites Web.
Obtenez-le: sharedlanguages.js
Utilise le:
<script src="acceptedlanguages.js"></script>
<script type="text/javascript">
console.log('Accepted Languages: ' + acceptedlanguages.accepted);
</script>
Il retourne toujours un tableau, classé par préférence des utilisateurs. Dans Safari & IE, le tableau est toujours de longueur simple. En FF et Chrome, il peut s’agir de plusieurs langues.
Manière Javascript:
var language = window.navigator.userLanguage || window.navigator.language;//returns value like 'en-us'
Si vous utilisez plugin jQuery.i18n , vous pouvez utiliser:
jQuery.i18n.browserLang();//returns value like '"en-US"'
Je ne trouve pas une seule référence indiquant que c'est possible sans impliquer le côté serveur.
MSDN sur:
De browserLanguage:
Dans Microsoft Internet Explorer 4.0 et versions antérieures, la propriété browserLanguage reflète la langue de l'interface utilisateur du navigateur installé. Par exemple, si vous installez une version japonaise de Windows Internet Explorer sur un système d'exploitation anglais, browserLanguage serait ja.
Dans Internet Explorer 5 et versions ultérieures, toutefois, la propriété browserLanguage reflète la langue du système d'exploitation, quelle que soit la version linguistique installée d'Internet Explorer. Toutefois, si la version multilingue de Microsoft Windows 2000 est installée, la propriété browserLanguage indique la langue définie dans les menus et les boîtes de dialogue actuels du système d'exploitation, comme indiqué dans les Options régionales du Panneau de configuration. Par exemple, si vous installez une version japonaise d'Internet Explorer 5 sur un système d'exploitation anglais (Royaume-Uni), browserLanguage serait en-gb. Si vous installez la version multilingue de Windows 2000 et définissez la langue des menus et des boîtes de dialogue en français, browserLanguage sera fr, même si vous disposez d'une version japonaise d'Internet Explorer.
Remarque Cette propriété n'indique pas la ou les langues définies par l'utilisateur dans les préférences de langue, situées dans la boîte de dialogue Options Internet.
De plus, il semble que browserLanguage
soit déconseillé car IE8 ne l’a pas répertorié.
Si vous développez une application/extension Chrome, utilisez le API chrome.i18n .
chrome.i18n.getAcceptLanguages(function(languages) {
console.log(languages);
// ["en-AU", "en", "en-US"]
});
Je viens juste de proposer ça. Il combine la nouvelle syntaxe de déstructuration JS avec quelques opérations standard pour récupérer la langue et les paramètres régionaux.
var [lang, locale] = (((navigator.userLanguage || navigator.language).replace('-', '_')).toLowerCase()).split('_');
J'espère que ça aide quelqu'un
Pour ce que cela vaut, la bibliothèque de sélecteurs de langue universelle de Wikimedia a des crochets pour cela: https://www.mediawiki.org/wiki/Extension:UniversalLanguageSelector
Voir la fonction getFrequentLanguageList dans resources/js/ext.uls.init.js. Lien direct: https://gerrit.wikimedia.org/r/gitweb?p=mediawiki/extensions/UniversalLanguageSelector.git;a=blob;f=resources/js/ext.uls.init.js;hb = HEAD
Cela dépend toujours du serveur, ou plus précisément de l'API MediaWiki. La raison pour laquelle je le montre est que cela peut fournir un bon exemple pour obtenir toutes les informations utiles sur la langue de l'utilisateur: langue du navigateur, Accept-Language, géolocalisation (avec obtention d'informations de pays/langue par le CLDR), et bien sûr, les préférences du site de l'utilisateur.
Si vous avez seulement besoin de supporter certains navigateurs modernes, vous pouvez maintenant utiliser:
navigator.languages
qui renvoie un tableau des préférences de langue de l'utilisateur dans l'ordre spécifié par l'utilisateur.
À compter de maintenant (septembre 2014), cela fonctionne sur: Chrome (v37), Firefox (v32) et Opera (v24)
Mais pas sur: IE (v11)
DanSingerman a une très bonne solution à cette question.
La seule source fiable pour la langue se trouve dans l'en-tête de requête HTTP. Vous avez donc besoin d'un script côté serveur pour répondre à l'en-tête de la requête ou au moins au champ Accept-Language
.
Voici un serveur très simple, Node.js, qui devrait être compatible avec le plugin 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');
Tout d'abord, excusez-moi pour mon anglais. Je voudrais partager mon code, parce que cela fonctionne et qu’il est différent des autres réponses données. Dans cet exemple, si vous parlez français (France, Belgique ou autre langue française), vous êtes redirigé sur la page française, sinon sur la page anglaise, en fonction de la configuration du navigateur:
<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>
La réponse de Dan Singerman pose un problème: l'en-tête récupéré doit être utilisé immédiatement, en raison de la nature asynchrone de la commande ajax de jQuery. Cependant, avec son serveur d'applications Google, j'ai écrit ce qui suit, de sorte que l'en-tête est défini dans le cadre de la configuration initiale et peut être utilisé ultérieurement.
<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>
Si vous avez le contrôle d'un backend et utilisez Django, une implémentation à 4 lignes de l'idée de Dan est:
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})
puis dans urls.py:
url(r'^browserlang/$', views.get_browser_lang, name='get_browser_lang'),
et sur le devant:
$.get(lg('SERVER') + 'browserlang/', function(data){
var lang_code = data.response.split(',')[0].split(';')[0].split('-')[0];
});
(vous devez bien sûr définir DEFAULT_LANG dans settings.py)
Si vous ne souhaitez pas utiliser un serveur externe et que vous en possédez un, vous pouvez utiliser un simple script PHP pour obtenir le même comportement que @DanSingerman answer.
languageDetector.php:
<?php
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
echo json_encode($lang);
?>
Et changez simplement ces lignes du script jQuery:
url: "languageDetector.php",
dataType: 'json',
success: function(language) {
nowDoSomethingWithIt(language);
}
Basé sur la réponse ici Accès aux en-têtes HTTP de la page Web en JavaScript J'ai construit le script suivant pour obtenir la langue du navigateur:
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();
}
J'ai un hack qui, à mon avis, utilise très peu de code et est assez fiable.
Placez les fichiers de votre site dans un sous-répertoire. SSL sur votre serveur et créez des liens symboliques vers ce sous-répertoire où sont stockés vos fichiers qui indiquent vos langues.
Quelque chose comme ça:
ln -s /var/www/yourhtml /var/www/en
ln -s /var/www/yourhtml /var/www/sp
ln -s /var/www/yourhtml /var/www/it
Utilisez votre serveur Web pour lire HTTP_ACCEPT_LANGUAGE et redirigez-les vers ces "sous-répertoires différents" en fonction de la valeur de langue fournie.
Vous pouvez maintenant utiliser le fichier window.location.href de Javascript pour obtenir votre URL et l'utiliser de manière conditionnelle pour identifier de manière fiable la langue de votre choix.
url_string = window.location.href;
if (url_string = "http://yoursite.com/it/index.html") {
document.getElementById("page-wrapper").className = "italian";
}
j'avais une approche différente, cela pourrait aider quelqu'un à l'avenir:
le client voulait une page où vous pouvez échanger des langues. J'avais besoin de formater les nombres avec ce paramètre (pas avec le navigateur ni avec aucun paramètre prédéfini)
donc je définis un paramètre initial en fonction des paramètres de configuration (i18n)
$clang = $this->Session->read('Config.language');
echo "<script type='text/javascript'>var clang = '$clang'</script>";
plus tard dans le script, j'ai utilisé une fonction pour déterminer ce que j'ai besoin deformulation numérique
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 : "."}
}
}
donc j'ai utilisé la langue définie de la page et comme solution de rechange, j'ai utilisé les paramètres du navigateur.
ce qui devrait être utile aux fins de test.
en fonction de vos clients, vous n'aurez peut-être pas besoin de ces paramètres.
Pour qui cherche Java solution de serveur
Voici 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();
}
Si vous utilisez ASP .NET MVC et que vous souhaitez obtenir l'en-tête Accepted-Languages à partir de JavaScript, voici un exemple de solution de contournement qui ne comporte aucune requête asynchrone.
Dans votre fichier .cshtml, stockez l'en-tête de manière sécurisée dans l'attribut data d'un attribut:
<div data-languages="@Json.Encode(HttpContext.Current.Request.UserLanguages)"></div>
Ensuite, votre code JavaScript peut accéder aux informations, par exemple. en utilisant 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>
Bien sûr, vous pouvez utiliser une approche similaire avec d’autres technologies de serveur, comme d’autres l'ont mentionné.