多言語サイトのNGINXを構成する



ユーザーが好む言語でサイトのコンテンツをレンダリングすることは、長い間良いフォームと考えられてきました。 一部のサーバーは、位置情報モジュールを使用してユーザーの位置の言語を決定しますが、他のサーバーはブラウザー設定を使用します。 多くの場合、ユーザーの言語設定はCookieに保存され、2回目のアクセスで使用されます。



ユーザーの言語を判断するのに最適な方法は、論点です。 言語情報の重要度の私の個人ランク(降順):Cookie、ブラウザ設定、地域。



検索エンジン、ソーシャルネットワーク、およびその他の情報アグリゲーターの場合、たとえばFacebookクロニクルのサムネイルとして、ページのインデックス作成またはロードが必要な言語を知ることが重要です。 これは、リンクが言語を一意に示す必要があることを意味します。



リソースに関する言語情報をエンコードするための一般的なオプションは次のとおりです。



最初のオプションは最も過激で、サイトの各言語バージョンは個別のリソースと見なされます。 SSL証明書に問題がある可能性があるため、SAN DNSホスト名ですべての可能なオプションを事前に提供するか、マスク付きの証明書(* .example.comなど)を注文する必要があります。



2番目のオプションは最も実用的です。言語の選択はURIに含まれます。つまり、リンクのインデックス作成とコピーに問題はありません。



3番目のオプションはあまり馴染みがなく、残りのGETパラメーターを追加するときに追加のロジックが必要であり、リンクをコピーするときにユーザーを混乱させる可能性があります。 パブリックリンクには最適なオプションではありません。

画像

NGINXサーバーに基づく2番目のオプションの実装について説明します。 最小限の変更で、説明した設定を最初のオプションに適用できます。



セットアップはいくつかのステップで構成されます。



まず、ブラウザの言語設定がチェックされます。 ユーザーがCookieを持っている場合、この値はブラウザーの設定を上書きします。 結果の値は$lang



変数に渡されます。



最初の段階で、言語情報を含むGETパラメーターを受信するようにバックエンドを構成する必要があります。 つまり、リストの3番目のオプションを実装していますが、システム内にあります。 例として、GETパラメーターlocale=< >



を検討し、2文字のコードISO 639-1を使用します。



http://<_back-end_>?locale=ru



などのリンクにアクセスしたときに、 http://<_back-end_>?locale=ru



がロシア語で応答することを確認する必要があります。

その後、フロントエンドでNGINXを構成できます。



2番目の段階は、ユーザーから言語設定を取得することです。 サーバーにアクセスすると、クライアントのブラウザに優先言語でCookieが設定されることがわかります。 Cookieは$ langと呼ばれます。



サイト構成に書き込みます



 map $http_accept_language $browser_lang { default en; ~ru ru; } map $cookie_lang $lang { default $browser_lang; ~en en; ~ru ru; }
      
      





まず、別の場所でタイプ/NN/*



リクエストを選択する必要があります。 変数を強調表示して正規表現を適用します。



 location ~ '^/(?<lang_code>[\D-]{2})/(?<rest_uri>.*)'
      
      





2文字のコードを変数$lang_code



、その他はすべて変数$rest_uri







また、関連する言語を既存の言語にリダイレクトすることもできます。たとえば、ウクライナ語やベラルーシ語のロケールの場合、英語よりもロシア語でサイトを表示することをお勧めします。



 if ($lang_code ~* (uk|be)) { return 301 http://$host/ru/$rest_uri$is_args$args; }
      
      





コードが不明な場合は、英語版のサイトが使用されます。



 if ($lang_code !~* (en|ru)) { return 301 http://$host/en/$rest_uri$is_args$args; }
      
      





if-constructionの場合、順序が重要です。 したがって、最初にユニットをコンプライアンスチェックに配置する必要があり、最後にのみ、非コンプライアンスチェックに配置する必要があります。



次に、GETリクエストでロケールパラメータを使用する可能性のあるユーザーリンクをクリアする必要があります。 ?locale=en&locale=ru



など、重複した引数が送信された場合のバックエンドの動作は不明?locale=en&locale=ru



。 したがって、ユーザーがリンクexample.com/en/?locale=ru



使用している場合、 locale=ru



バックエンドに送信しない方locale=ru



適切です。



 if ($args ~ (.*)locale=[^&]*(.*)) { set $args $1$2; }
      
      





繰り返し発生するアンパサンドを削除する



  if ($args ~ (.*)&&+(.*)) { set $args $1&$2; }
      
      





最初にアンパサンドを削除します



 if ($args ~ ^&(.*)) { set $args $1; }
      
      





最後にアンパサンドを削除します



 if ($args ~ (.*)&$) { set $args $1; }
      
      





あとは、必要なパラメーターをバックエンドに渡すだけです。 私の例では、すべてがupstream



構成セクションでバックエンドとして登録されたサーバーのグループに送られます。



 proxy_pass http://back-end/$rest_uri?locale=$lang_code&$args;
      
      





最終的な構成は次のようになります

 ## get locale map $http_accept_language $browser_lang { default en; ~ru ru; } map $cookie_lang $lang { default $browser_lang; ~en en; ~ru ru; } upstream back-end { ip_hash; server 172.21.71.15:8080; # vm-deb-osl-scala-1 server 172.21.71.16:8080; # vm-deb-osl-scala-2 server 172.21.71.17:8080; # vm-deb-osl-scala-3 server 172.21.71.18:8080; # vm-deb-osl-scala-4 keepalive 32; } server { listen 109.233.59.100:80; server_name ruvpn.net; location / { # Redirect to locale return 301 http://$host/$lang$uri$is_args$args; } # Handle URL with locale location ~ '^/(?<lang_code>[\w-]{2})/(?<rest_uri>.*)' { # Redirect to Russian for some CIS countries if ($lang_code ~* (uk|be|kk)) { return 301 http://$host/ru/$rest_uri$is_args$args; } # Redirect to English for unknown languages if ($lang_code !~* (en|ru)) { return 301 http://$host/en/$rest_uri$is_args$args; } if ($args ~ (.*)locale=[^&]*(.*)) { set $args $1$2; } # Cleanup any repeated & introduced if ($args ~ (.*)&&+(.*)) { set $args $1&$2; } # Cleanup leading & if ($args ~ ^&(.*)) { set $args $1; } # Cleanup ending & if ($args ~ (.*)&$) { set $args $1; } proxy_pass http://back-end/$rest_uri?locale=$lang_code&$args; include /etc/nginx/proxy.conf; }
      
      





実際のサイトでどのように機能するかを確認できます。 設定例からすでに気づいたように、リソースhttp://ruvpn.netはこのスキームに従って設定されています。 ruvpn.net/en/product/details/4などのすべてのリクエストはページをロシア語で表示しますが、リクエストruvpn.net/sv/product/details/4ruvpn.net/en/product/details/4にリダイレクトされます 、サイトのスウェーデン語版が存在しないため。 ruvpn.netのルートリンクに移動すると、言語設定に応じて、自動的にruvpn.net/ruまたはruvpn.net/enにリダイレクトされます。

説明されている方法の唯一の欠点は、URIの先頭にある2文字のリンクを、言語の選択以外のものに使用できないことです。 しかし、これはサイトアーキテクチャの問題であり、設計中に簡単に解決できます。



All Articles