Получение региона пользователя с помощью navigator.язык

в течение некоторого времени я использовал что-то вроде этого, чтобы получить страну моего пользователя (ISO-3166):

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

Я всегда предположить эта строка будет похожа на en-US -- где страна будет проводить 2 место массива.

Я думаю, что это предположение неверно. согласно MDN docs, navigator.language возвращает: "строка, представляющая языковую версию, определенную в BCP 47." чтение BCP 47, основной язык подметки гарантированно быть первым (например, 'ан'), но кода региона не гарантируется, 2-й подметки. Могут быть подзаголовки, которые предшествуют и следуют подзаголовку региона.

"sr-Latn-RS" является допустимым языковым тегом BCP 47:

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

- это значение, возвращаемое из navigator.language подмножество BCP 47, содержащее только язык и регион? Или есть библиотека или регулярное выражение, которые обычно используются чтобы извлечь подзаголовок региона из языкового тега?

6 ответов


ваше решение основано на ложном предположении, что языковой тег браузера надежно соответствует стране пользователя. Например, Я установил язык браузера на немецкий, хотя в данный момент я живу далеко не в Германии, а скорее в Соединенных Штатах.

кроме того, например, во многих языковых пакетах Chrome не требуется указывать модификатор региона. Настройка языка отображения Chrome на немецкий

enter image description here

обеспечивает следующий языковой тег:

> navigator.language
< "de"

нет тега региона вообще, и довольно распространенный язык.

суть в том, что моя настройка браузера приводит к языковому тегу de, хотя я живу в Соединенных Штатах.


более точным и, возможно, надежным способом определения местоположения пользователя было бы получить его из IP-адреса, связанного с запросом. Существует множество услуг, которые предлагают эту услугу. ip-api.com один из они:

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

в Firefox вы можете выбрать настройки языка в настройках:

enter image description here

список языков содержит 269 элементов, 192 из которых не включают код региона.

регион полезен только тогда, когда язык имеет разные варианты в зависимости от местоположения. Таким образом, пользователи могут сообщить серверу, на каком языке они предпочитают отвечать.

не использовать этот подход для поиска пользователя. Это слишком ненадежно, потому что пользователь не может указать какой-либо регион или потому что пользователь может физически находиться в другом месте.

Если вы хотите найти пользователя, вы должны использовать API геолокации.


регулярное выражение найдено здесь: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'

будьте осторожны, у вас есть navigator.language и navigator.languages.

langage:

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

langages :

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

найти страны Википедия по ISO 3166-1 или используйте javascript lib:


как сказал @TimoSta,

попробуй такое

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

С получить язык посетителей и код страны с javascript (на стороне клиента). См. ответ @noducks


получаемое значение происходит из заголовка Accept-Language HTTP-запроса.

значения заголовка могут быть довольно сложными, как

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

как следует из названия, заголовок Accept-Language в основном определяет приемлемые языки, а не страны.

тег языка может содержать также дополнительную информацию о местоположении, как в "en-GB", но другие, такие как "en", этого не делают.

в случае, если нет, просто нет информации о страна.

также не всегда возможно точно сопоставить язык, такой как "en", со страной. Если язык "en", страна может быть "GB", но это также может быть "US".

что вы можете сделать ;

  • определите только страну, если язык содержит один, как в "en-GB"
  • если язык не содержит страну, у вас есть следующие варианты :
  • несколько языков используются только в одной стране, как "da", датский на котором говорят только в Дании (я предполагаю здесь), поэтому вы можете отобразить эти случаи.
  • вы можете использовать значение по умолчанию для других случаев, в зависимости от языка, например map 'en' to 'GB'
  • вы можете использовать общее значение по умолчанию, как " US " для всех случаев ни одна страна не может быть определена.
  • вы можете использовать дополнительную информацию, например, IP-адрес клиентов, чтобы определить страну
  • наконец, вы можете попросить пользователя ввести в стране

I собрал дополнительную информацию о заголовке Accept-Language здесь