Nginx プロキシを使用してフロントエンドのクロスドメイン問題を解決する方法

Nginx プロキシを使用してフロントエンドのクロスドメイン問題を解決する方法

序文

Nginx (「エンジン エックス」と発音) は、リバース プロキシ、ロード バランサ、HTTP キャッシュとしても使用できる非同期フレームワーク Web サーバーです。

この記事では、Web フロントエンドとバックエンドの分離開発において、Nginx を使用してルーティング転送を実装する方法について説明します。

Web 開発では通常、フロントエンドとバックエンドを分離する開発モデルが使用されます。つまり、フロントエンドとバックエンドは別々に開発され、フロントエンドは Ajax を介してバックエンド インターフェイスを要求してデータを取得し、ページにデータをレンダリングします。フロントエンド開発では、スキャフォールディングを使用してフロントエンド開発環境を構築します。通常、基礎となるレイヤーは、Node.js の Express フレームワークを使用してローカル サーバーを起動します。バックエンドはインターフェースを提供します。これは通常、開発のためにドメイン名でオンラインに配置されます。

これにより、開発プロセス中にクロスドメインの問題が発生し、あるドメイン名の Web ページが Ajax を介して別の (異なるオリジンの) ドメイン名のインターフェイス API を要求できなくなります。これはブラウザの同一オリジンポリシーであり、ブラウザの非常に重要なセキュリティポリシーです。

この問題の解決策の 1 つはプロキシを使用することです。具体的には、サーバーがローカルで起動され (localhost:4000 など)、サーバーに送信されたリクエストはリクエスト ルーティング (URL にプレフィックス /api があるかどうかの判断など) に従って転送され、フロントエンド開発サーバー (localhost:3000 など) とバックエンド サーバー (dev.yoursite.com など) に転送されます。このように、プロキシ サーバーを経由すると、要求された API はすべて同じドメイン名の下にあるため、当然、クロスドメインの問題は発生せず、要求の失敗につながることはありません。

次に、Nginx を使用してリバース プロキシを実装する方法について説明します。

Nginx 設定ファイルの簡単な紹介

Nginx をインストールした後、Nginx のデフォルト設定ファイルの場所を決定する必要があります。 nginx -t コマンドを実行すると、nginx のデフォルト設定ファイルの構文が正しいかどうかが検出され、テストが実行され、最後に結果が出力されます。出力からデフォルトの構成ファイルの場所を取得できます。

nginx: 設定ファイル /etc/nginx/nginx.conf の構文は正常です
nginx: 設定ファイル /etc/nginx/nginx.conf のテストが成功しました

デフォルトの設定ファイルの場所を取得する別の方法として、nginx -h を実行する方法があります。このコマンドは、nginx の簡単なヘルプ ドキュメントを出力します。このドキュメントでは、-c filename の構成項目の説明に、デフォルトの構成項目のパスも示されます。

-c ファイル名: 設定ファイルを設定します (デフォルト: /etc/nginx/nginx.conf)

このドキュメントから、-c 構成項目を使用して構成ファイルをカスタマイズできることもわかります。ファイルが指定されていない場合は、デフォルトの構成ファイルが使用されます。

次に、プロキシ機能を有効にするために、Nginx のデフォルト設定ファイル nginx.config を変更します。

nginx.config ファイルの http の後のコード ブロックには、次のような行があるはずです。

/etc/nginx/conf.d/*.conf を含めます。

このコード行の目的は、/etc/nginx/conf.d ディレクトリ内のサフィックス .conf を持つファイルの内容をインポート場所に埋め込み、構成の一部として実行することです。

macOS に Nginx をインストールした場合は、状況が少し異なる可能性があります。 brew を使用してインストールした Nginx には include servers/*; があり、これによりすべてのファイルが servers ディレクトリに埋め込まれます。

この埋め込み構文が使用されるのはなぜですか?この方法により、異なるプロジェクトに必要な構成を異なる構成ファイルに配置できるため、他のプロジェクトの構成を誤って変更してしまう心配をすることなく、対応するプロジェクト用に変更する構成ファイルをすばやく見つけることができるという利点があります。また、nginx.conf 上で直接変更すると肥大化します。これは、デザイン パターンの単一責任の原則に準拠しています。

さらに、conf.d ディレクトリの名前に .d が追加されているのはなぜか疑問に思うかもしれません。 Linux をしばらく使用している場合は、httpd、crond、vsftpd などの一部のディレクトリまたはファイルの末尾に d が追加されていることに気付くでしょう。実際、これはこれらのファイルがすべてデーモン (サービス) であることを示しています。ここでのサービスとはシステムサービスを指し、主にシステム自体に必要なサービスとネットワークを担当するサービスに分けられます。私たちの conf.d は後者に属します。

Nginx 設定ファイルの記述

conf.d ディレクトリに demo.conf というファイルを作成し、以下の内容を記述して Nginx を起動します。

サーバー{
 5000を聴く;
 server_name ローカルホスト;

 位置 / {
 proxy_pass http://localhost:3000;
 }
 場所 /api/ {
 proxy_pass http://localhost:4000;
 }
}

この構成により、localhost:5000 のサーバーが有効になり、/api/ で始まる URL リクエストが localhost:5000 から localhost:4000 (バックエンド インターフェイス サーバー) にプロキシされます。その他のリクエストは localhost:3000 (フロントエンド) にプロキシされます。次に、設定ファイル内の内容の機能について詳しく分析します。

listen はサーバーのポート番号を設定し、server_name はホスト名を設定します。

位置

location はルートに一致することを意味します。一致すると、対応するコード ブロック内の操作が実行されます。 location では、プレフィックス一致と通常の一致 (~* または ~ で始まる必要があります) を使用できます。ここで使用する構成では、プレフィックス マッチングを使用します。

ここで注意すべき点が 1 つあります。Nginx のルート マッチングは、最初のルートを順番にマッチングする一般的なルート マッチング スキーム (バックエンドの gin とフロントエンドの vue-router のルート マッチング スキームなど) とは異なります。Nginx は、次の方法でルートをマッチングします。

  1. まず、プレフィックス マッチングを実行し、すべてのプレフィックス マッチを走査して、プレフィックス マッチが最も長いものを選択します。
  2. 次に、通常の一致が実行され、すべての通常の一致の中で、前から後ろに向かって最初に一致するものが選択されます。
  3. 一致する正規表現が見つかった場合は、それに対応する構成が使用されます。見つからない場合は、以前に見つかった最長のプレフィックス一致に対応する構成が使用されます。

したがって、リクエストが localhost:5000/api/xx の場合、/ と /api/ の両方がプレフィックス一致になる可能性があります。ルールによれば、先頭の / もプレフィックス一致を満たしていますが、/api の方が長いため、最終的に一致するのは /api です。

プロキシパス

一致する場所を決定した後、proxy_pass が何を行うかを見てみましょう。 proxy_pass は、要求ルートを指定されたプロトコルとアドレスにマッピングするために使用されます。本質は、Nginx に送信されたリクエストを処理して別のサーバーに送信し、返されたデータを Nginx の戻りデータとして返すことです。

proxy_pass の後に URI が使用されている場合 (ポートの後に少なくとも 1 つの / が含まれる)、Nginx は場所に一致する文字を置き換えます。

5000を聴く;
server_name ローカルホスト;
場所 /名前/ {
 プロキシパス http://127.0.0.1/remote/; 
}
# ローカルホスト:5000/名前/fstar
# マッピングされたリクエストは # 127.0.0.1/remote/fstar になります

ご覧のとおり、マッピング中に /name/ 部分が削除 (または置換) されます。

proxy_pass の後に URI が続かない場合 (ポートの後に何もない場合)、Nginx はソース要求をプロキシされたサービスに完全にマッピングします。

5000を聴く;
server_name ローカルホスト;
場所 /some/path/ {
 プロキシパス http://127.0.0.1;
}

# ローカルホスト:5000/some/path/x/y
# 127.0.0.1/some/path/x/y にマッピングされます

ここでは /some/path は削除されません。

demo.conf ファイルの proxy_pass は URI を使用しないため、ルートは完全に別のサービスにマップされます。

検討すべき質問

すみません、下記に2つの設定があります(違いはproxy_passの末尾に/があるかどうかです)? /kite/api/xx をリクエストすると、何にマッピングされますか?

場所 /kite/api/ {
 proxy_pass http://localhost:5000;
}
場所 /kite/api/ {
 proxy_pass http://localhost:5000/;
}

先ほど proxy_pass についてお話しした際に、proxy_pass の後に URI がない場合は正常に転送され、URI の場合は location に一致するプレフィックスが削除されてから転送されると述べました。これは、ルートを置き換える効果を反映しています。上記の 2 つの構成の違いは、末尾の / にあります。/ がある構成は URI ですが、/ がない構成は URI ではないため、それぞれまったく異なる結果になります。

http://localhost:5000/kite/api/xx
http://localhost:5000/xx

したがって、Nginx の設定を記述する際には、ポートの後の / を保持する必要があるかどうかに注意してください。なぜなら、それが存在するか存在しないかによって、まったく異なる 2 つの効果が生じるからです。

参考文献

  • Nginx 公式ドキュメント
  • NGINX のプロキシ応答で URL を書き換えるにはどうすればいいですか?

要約する

Nginx プロキシを使用してフロントエンドのクロスドメイン問題を解決する方法についての記事はこれで終わりです。Nginx プロキシを使用してフロントエンドのクロスドメイン問題を解決する方法に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Nginx を使用してフロントエンドのクロスドメイン問題を解決する方法
  • Nginx がフロントエンド リソースへのクロスドメイン アクセスの問題をどのように解決するかの詳細な説明

<<:  フロントエンドの面接でよく聞かれる JavaScript の質問の完全なリスト

>>:  MySQLデータのセキュリティを確保するための提案

推薦する

WeChat アプレット wxss で外部 CSS ファイルとアイコンフォントを参照する方法

原因外部ファイルをミニプログラムにインポートする方法は次のとおりです: @import "...

DockerにNginxをインストールする方法

DockerにNginxをインストールするNginx は、IMAP/POP3/SMTP サービスも提...

CSSスタイルは、テキストが長すぎる場合に省略記号を表示する問題を解決します

1. CSSスタイルは、テキストが長すぎる場合に省略記号を表示する問題を解決します1. 一般的なスタ...

HTML マークアップ言語 - リファレンス

123WORDPRESS.COM HTML チュートリアル セクションに戻るには、ここをクリックして...

MySQL累積計算実装方法の詳しい説明

目次序文需要分析MySQL ユーザー変数累積計算にMysqlユーザー変数を使用する要約するこの記事で...

CentOS 7 で RPM を使用して mysql5.7.13 をインストールする

0. 環境この記事のオペレーティング システム: CentOS 7.2.1511 x86_64 My...

VMware インストール後に仮想ネットワーク カードが表示されない問題について

1 問題の説明: 1.1 Windows 10 に VMware を初めてインストールする場合、また...

CSS3 メディアクエリにおけるデバイス幅と幅の違いの詳細な説明

1.デバイス幅定義: 出力デバイスの画面表示幅を定義します。 Web ページが Safari で開か...

MySQL 8.0 ディクショナリテーブル拡張の詳細な説明

MySQL のデータ ディクショナリは、データベースの重要なコンポーネントの 1 つです。INFOR...

Dockerはポートマッピングを設定しますが、ソリューションにアクセスできません

#docker ps チェック、すべてのポートがマップされています コンテナID イメージ コマンド...

Webpack コンポーネントの使用状況統計を実装するための 50 行のコード

背景最近、リーダーからコンポーネント ライブラリを構築するように依頼があり、プロジェクトで現在使用さ...

jsを使用してスライダーをドラッグする効果を実現します

この記事では、jsでスライダーをドラッグする方法の具体的なコードを参考までに共有します。具体的な内容...

Win10 64ビットMySQL8.0のダウンロードとインストールのチュートリアル図

公式サイトから MySQL をダウンロードしてインストールし、クライアントにログインするにはどうすれ...

MySQL 8.0.15 のダウンロードとインストールの詳細なチュートリアルは初心者にとって必須です。

この記事では、MySQL 8.0.15をダウンロードしてインストールするための具体的な手順を参考まで...

JavaScript は単一のリンクリストプロセス分析を実装します

序文:複数の要素を格納するために、配列は最も一般的に使用されるデータ構造ですが、配列には多くの欠点も...