web-dev-qa-db-fra.com

Obtenir la région de l'utilisateur avec navigator.language

Depuis quelque temps, j'utilise quelque chose comme ceci pour obtenir le pays de mon utilisateur (ISO-3166):

const region = navigator.language.split('-')[1]; // 'US'

J'ai toujours supposé la chaîne serait semblable à en-US - où le pays détiendrait la 2ème position du tableau. 

Je pense que cette hypothèse est incorrecte. Selon la documentation MDN , navigator.language renvoie: "chaîne représentant la version de langue définie dans BCP 47."Lecture de BCP 47 , la sous-étiquette de langue principale est garantie en premier , 'en') mais le code de région n’est pas garanti comme étant la 2e sous-étiquette. Il peut y avoir des sous-étiquettes qui précèdent et suivent la sous-étiquette de région. 

Par exemple, "sr-Latn-RS" est une balise de langue BCP 47 valide:

sr                |  Latn           |  RS
primary language  |  script subtag  |  region subtag

La valeur renvoyée par navigator.language est-elle un sous-ensemble du BCP 47 contenant uniquement la langue et la région? Ou existe-t-il une bibliothèque ou une expression régulière couramment utilisée pour extraire la sous-étiquette region d'une étiquette de langue?

15
Jeff

Regex trouvé ici: https://github.com/gagle/node-bcp47/blob/master/lib/index.js

var re = /^(?:(en-GB-oed|i-AMI|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-Lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))$|^((?:[a-z]{2,3}(?:(?:-[a-z]{3}){1,3})?)|[a-z]{4}|[a-z]{5,8})(?:-([a-z]{4}))?(?:-([a-z]{2}|\d{3}))?((?:-(?:[\da-z]{5,8}|\d[\da-z]{3}))*)?((?:-[\da-wy-z](?:-[\da-z]{2,8})+)*)?(-x(?:-[\da-z]{1,8})+)?$|^(x(?:-[\da-z]{1,8})+)$/i;

let foo = re.exec('de-AT');      // German in Austria
let bar = re.exec('zh-Hans-CN'); // Simplified Chinese using Simplified script in mainland China

console.log(`region ${foo[5]}`); // 'region AT'
console.log(`region ${bar[5]}`); // 'region CN'
1
Jeff

Votre solution repose sur l'hypothèse fausse que la balise de langue du navigateur correspond de manière fiable au pays de l'utilisateur. Par exemple, la langue de mon navigateur est l'allemand, même si je ne vis nulle part près de l'Allemagne pour le moment, mais plutôt aux États-Unis.

En outre, par exemple, dans Chrome, de nombreux packs de langue ne vous obligent pas à spécifier le modificateur de région. Définition de la langue d'affichage de Chrome en allemand

 enter image description here

fournit la balise de langue suivante:

> navigator.language
< "de"

Aucune étiquette de région et une langue assez commune.

En bout de ligne, la configuration de mon navigateur génère le tag de langue de, même si je vis aux États-Unis.


Un moyen plus précis et éventuellement fiable de déterminer l'emplacement de l'utilisateur serait de le déduire de l'adresse IP associée à la demande. Il existe de nombreux services qui offrent ce service. ip-api.com est l'un d'entre eux:

$.get("http://ip-api.com/json", function(response) {
  console.log(response.country);     // "United States"
  console.log(response.countryCode); // "US"
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

5
Timo

Attention, vous avez navigator.language et navigator.languages.

langue:

 console.log(navigator.language); // "fr"

langages:

 console.log(navigator.languages); // ["fr", "fr-FR", "en-US", "en"]

Pour trouver des pays, voir Wikipedia sur ISO 3166-1 ou utilisez javascript lib:

1
A-312

Dans Firefox, vous pouvez choisir vos paramètres de langue dans les préférences:

 enter image description here

La liste des langues contient 269 éléments, dont 192 n’incluent aucun code de région.

La région n'est utile que lorsqu'une langue a différentes variantes en fonction de l'emplacement. Ainsi, les utilisateurs peuvent indiquer au serveur dans quelle variante de langue ils préfèrent que la réponse soit.

N'utilisez pas cette approche pour localiser l'utilisateur. C'est trop peu fiable, parce que l'utilisateur peut ne pas spécifier de région ou parce qu'il peut être physiquement à un autre endroit.

Si vous souhaitez localiser l'utilisateur, vous devez utiliser le API de géolocalisation .

1
Oriol

La valeur que vous recevez provient de l'en-tête Accept-Language de la requête HTTP.

Les valeurs de l'en-tête peuvent être assez complexes comme 

Accept-Language: da, en-GB;q=0.8, en;q=0.7

Comme son nom l'indique, l'en-tête Accept-Language définit fondamentalement les langues acceptables, pas les pays.

Une balise de langue peut également contenir des informations de lieu supplémentaires, comme dans "en-GB", mais d'autres comme "en" n'en contiennent pas.

Dans le cas contraire, il n'y a aucune information sur le pays.

Il n'est également pas toujours possible de mapper exactement une langue comme "en" sur un pays . Si la langue est "en", le pays peut être "GB" mais il peut également être "US".

Ce que tu peux faire ;

  • Déterminer le pays uniquement, si la langue en contient un, comme en 'GB'
  • Si la langue ne contient pas de pays, vous avez les options suivantes:
  • Quelques langues ne sont utilisées que dans un pays, comme «da», le danois qui n'est parlé qu'au Danemark (je suppose ici), vous pouvez donc cartographier ces cas.
  • Vous pouvez utiliser une valeur par défaut pour d'autres cas, en fonction de la langue, par exemple. map 'en' à 'GB'
  • Vous pouvez utiliser une valeur par défaut telle que "US" pour tous les cas. Aucun pays ne peut être déterminé.
  • Vous pouvez utiliser des informations supplémentaires, par exemple l'adresse IP du client pour déterminer le pays
  • Enfin, vous pouvez demander à l'utilisateur d'entrer le pays

J'ai collecté des informations supplémentaires sur l'en-tête Accept-Language ici

Comme @TimoSta l'a dit,

Essaye ça 

$.getJSON('http://freegeoip.net/json/', function(result) {
   alert(result.country_code);
});

from Obtenir la langue des visiteurs et le code pays avec javascript (côté client) . Voir la réponse de @noducks

0
HongZhen Liu