数十の言語にローカライズされたWebサイト(Flash)があり、コンテンツにアクセスする手順を最小限に抑えるために、ユーザーのブラウザー設定に応じてデフォルト値を自動定義したい。
参考までに、プロキシの制限のためにサーバースクリプトを使用できないため、問題を解決するにはJavaScriptまたはActionScriptが適切だと思います。
質問:
ユーザーのロケールを「推測」する最良の方法は何でしょうか?
私を助けることができる既存の単純なクラス/関数はありますか(複雑なローカリゼーションバンドルはありません)?特に、すべての可能な言語をスマートな方法でより小さな数(私が持っている翻訳)に分解するために。
そのようなソリューションはどの時点まで信頼できますか?
他の回避策や提案はありますか?
適切な方法は、サーバーに送信されたHTTP Accept-Language ヘッダーを確認することです。これには、ユーザーがブラウザを優先するように設定した言語の順序付きの重み付きリストが含まれます。
残念ながら、このヘッダーはJavaScript内の読み取りには使用できません。取得できるのはnavigator.language
だけです。これは、インストールされたWebブラウザーのローカライズされたバージョンを示します。これは、必ずしもユーザーの優先言語と同じではありません。 IEでは、代わりにsystemLanguage
(OSインストール言語)、browserLanguage
(language
と同じ)、userLanguage
(ユーザー設定のOSリージョン)が表示されますが、これらはすべて同様に役に立ちません。
これらのプロパティのいずれかを選択する必要がある場合は、最初にuserLanguage
を探し、language
に戻り、その後(使用可能な言語と一致しなかった場合)browserLanguage
を見て、最後にsystemLanguage
を探します。
単にAccept-Languageヘッダーを読み取り、ヘッダー値を文字列に含むJavaScriptファイルとして出力するサーバー側スクリプトをネット上の別の場所に配置できる場合、たとえば:
var acceptLanguage= 'en-gb,en;q=0.7,de;q=0.3';
次に、HTMLでその外部サービスを指す<script src>を含め、JavaScriptを使用して言語ヘッダーを解析できます。ただし、Accept-Language解析はほとんど常にサーバー側で実行されるため、これを行うための既存のライブラリコードは知りません。
結局何をするにしても、ユーザーによっては常に間違っていると推測されるため、ユーザーオーバーライドが必要になります。多くの場合、URLに言語設定を配置するのが最も簡単で(例:http://www.example.com/en/site vs http://www.example.com/de/site)、ユーザーにクリックさせます2つの間のリンク。両方の言語バージョンに単一のURLが必要な場合があります。その場合、設定をCookieに保存する必要がありますが、Cookieと検索エンジンのサポートがないユーザーエージェントを混乱させる可能性があります。
ChromeおよびFirefox 32以降では、navigator.languagesにはユーザーの設定順にロケールの配列が含まれ、navigator.languageよりも正確ですが、下位互換性を確保するために(テスト済みChrome/IE/Firefox/Safari)、次にこれを使用します。
function getLang()
{
if (navigator.languages != undefined)
return navigator.languages[0];
else
return navigator.language;
}
この記事 は、ブラウザのnavigatorオブジェクトの次のプロパティを提案します。
これらをjavascript関数にロールすると、ほとんどの状況で適切な言語を推測できるはずです。 javascriptがない場合やメソッドが機能しない場合でも、ユーザーが決定できるように、言語選択リンクを含むdivを用意してください。動作する場合は、divを非表示にします。
クライアント側でこれを行う際の唯一の問題は、クライアントに言語を提供するallか、スクリプトが実行されて言語を検出するまで待つ必要があることです。適切なバージョンをリクエストします。おそらく、最も人気のある言語バージョンをデフォルトとして提供することは、最も少数の人々を苛立たせるでしょう。
編集:IvanのCookieの提案を2回目にしますが、ユーザーが後で言語をいつでも変更できることを確認してください。誰もがブラウザのデフォルトの言語を好むわけではありません。
ブラウザがユーザーの言語を保存するために使用している複数の方法を組み合わせて、この関数を取得します。
const getNavigatorLanguage = () => {
if (navigator.languages && navigator.languages.length) {
return navigator.languages[0];
} else {
return navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en';
}
}
最初にnavigator.languages
配列の最初の要素を確認します。
その後、navigator.userLanguage
またはnavigator.language
を取得します。
これが失敗すると、navigator.browserLanguage
が返されます。
最後に、他のすべてが失敗した場合は、'en'
に設定します。
そして、これがセクシーなワンライナー:
const getNavigatorLanguage = () => (navigator.languages && navigator.languages.length) ? navigator.languages[0] : navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en';
ユーザーの優先言語とシステム/ブラウザのロケールには違いがあります。
ユーザーはブラウザで優先言語を構成できます。これらはnavigator.language(s)
に使用され、サーバーからリソースを要求するときに使用され、言語優先度のリストに従ってコンテンツを要求します。
ただし、ブラウザのロケールによって、数値、日付、時刻、通貨のレンダリング方法が決まります。この設定はおそらく最高ランクの言語ですが、保証はありません。 MacおよびLinuxでは、ユーザーの言語設定に関係なく、システムによってロケールが決定されます。 Windowsでは、Chromeの優先リストにある言語から選択できます。
Intl( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl )を使用することにより、開発者はこれらのレンダリングに使用するロケールをオーバーライド/設定できます。ただし、<input type="date">
形式など、オーバーライドできない要素があります。
この言語を適切に抽出するための唯一の方法は、次のとおりです。
(new Intl.NumberFormat()).resolvedOptions().locale
(Intl.NumberFormat().resolvedOptions().locale
も機能しているようです)
これにより、デフォルトロケールの新しいNumberFormatインスタンスが作成され、解決されたオプションのロケールが読み戻されます。
また、ドキュメントの言語を最初の呼び出しポートとするドキュメントから取得してから、多くの人が自分のJS言語をドキュメントの言語に一致させたいため、他の手段にフォールバックすることもできます。
HTML5:
document.querySelector('html').getAttribute('lang')
レガシー:
document.querySelector('meta[http-equiv=content-language]').getAttribute('content')
人々は間違った言語を単純に入力する可能性があるため、必ずしも100%信頼できる実際のソースはありません。
コンテンツごとに言語を判別できる言語検出ライブラリがあります。