web-dev-qa-db-ja.com

navigator.languageを使用してユーザーの地域を取得する

しばらくの間、ユーザーの国(ISO-3166)を取得するために次のようなものを使用しています:

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

私はいつも仮定文字列はen-USに似ています--国が配列の2番目の位置

この仮定は間違っていると思いますMDNドキュメントに従ってnavigator.languageは次を返します: "BCP 47で定義されている言語バージョンを表す文字列。"BCPの読み取り47 、一次言語サブタグが最初であることは保証されていますが(たとえば、 'en')、地域コードは2番目のサブタグであることは保証されていません。リージョンサブタグの前後にサブタグがある場合があります。

たとえば、"sr-Latn-RS"は有効なBCP 47言語タグです:

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

navigator.languageから返される値は、言語と地域のみを含むBCP 47のサブセットですか?または、言語タグから領域サブタグを抽出するために一般的に使用されるライブラリまたは正規表現はありますか?

18
Jeff

ここにある正規表現: 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

このソリューションは、ブラウザーの言語タグがユーザーの国と確実に一致するという誤った前提に基づいています。たとえば、私は現在、ドイツの近くではなく米国に住んでいるにもかかわらず、ブラウザの言語をドイツ語に設定しています。

また、たとえばChromeでは、多くの言語パックで地域修飾子を指定する必要がありません。 Chromeの表示言語をドイツ語に設定する

enter image description here

は次の言語タグを提供します。

> navigator.language
< "de"

リージョンタグはまったくなく、かなり一般的な言語です。

要するに、私が米国に住んでいても、ブラウザの設定で言語タグdeが表示されます。


ユーザーの場所を特定するより正確で信頼性の高い方法は、要求に関連付けられたIPアドレスからそれを導出することです。このサービスを提供するサービスは多数あります。 ip-api.com はその1つです。

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

navigator.languageおよびnavigator.languages

言語:

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

言語:

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

国を見つけるには、 ISO 3166-1のウィキペディア を参照するか、javascript libを使用します。

1
A-312

Firefoxでは、プリファレンスで言語設定を選択できます。

enter image description here

言語のリストには269項目あり、そのうち192項目には地域コードが含まれていません。

地域は、言語が場所によって異なるバリアントを持っている場合にのみ役立ちます。このようにして、ユーザーはサーバーがどの言語バリアントで応答するかを指定できます。

この方法を使用してユーザーを特定しないでください。ユーザーが領域を指定していないか、ユーザーが物理的に別の場所にいる可能性があるため、信頼性が高すぎます。

ユーザーを検索する場合は、 Geolocation API を使用する必要があります。

1
Oriol

受信する値は、HTTPリクエストのAccept-Languageヘッダーに由来します。

ヘッダーの値は次のように非常に複雑になる可能性があります

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

名前が示すように、Accept-Languageヘッダーは、基本的に国ではなく、受け入れ可能な言語を定義します。

言語タグには、「en-GB」のような追加の位置情報も含まれる場合がありますが、「en」のような他の場所には含まれません。

そうでない場合、国に関する情報はありません。

また、「en」のような言語を国に正確にマッピングすることが常に可能であるとは限りません。言語が「en」の場合、国は「GB」かもしれませんが、「US」かもしれません。

あなたができること;

  • 「en-GB」のように、言語に含まれている場合は国のみを特定します
  • 言語に国が含まれていない場合は、次のオプションがあります。
  • デンマークでしか話されないデンマーク語(da)のように、いくつかの国の言語は1つの国でのみ使用されます(私はここで推測しています)。これらのケースをマッピングできます。
  • 言語に応じて、他のケースではデフォルトを使用できます。 「en」を「GB」にマップする
  • 国を特定できない場合はすべて、「US」などの一般的なデフォルトを使用できます。
  • 追加情報を使用できます。国を決定するクライアントのIPアドレス
  • 最後に、ユーザーに国の入力を求めることができます

Accept-Languageヘッダーに関する追加情報を収集しました here

@TimoStaが言ったように、

これを試して

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

from JavaScriptで訪問者の言語と国コードを取得する(クライアント側) 。 @noducksの回答を見る

0
Hongzhen Liu