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

CSS 属性値正規マッチングセレクターの使い方 (ヒント)

属性値の正規一致セレクターには 3 つの種類があります。 [属性^="値"] [...

Linux の crontab タスク スケジューリングの簡単な分析

1. スケジュールタスクを作成する命令crontab -eは現在のユーザーの編集インターフェースに入...

検証コード干渉を実装する js (静的)

この記事では、検証コード干渉を実装するためのjsの具体的なコードを参考までに共有します。具体的な内容...

2つのNode.jsプロセスがどのように通信するかの詳細な説明

目次序文異なるコンピュータ上の 2 つの Node.js プロセス間の通信TCPソケットの使用HTT...

Web デザイン体験: 5 つの優れた Web デザイン コンセプトの完全分析 (画像)

他の種類のデザインとは異なり、Web デザインは時代の発展とともに常に変化しています。したがって、W...

Web ページの HTML コードの説明: 順序付きリストと順序なしリスト

このセクションでは、HTML のリスト要素について学習します。リストは、Web サイトのデザインにお...

WeChatミニプログラムで検索キーワードを強調表示するサンプルコード

1. はじめにプロジェクトで要件に遭遇したら、データを検索してキーワードを強調表示します。要件を受け...

MySQL ジョイントテーブル更新デー​​タの詳細な例

1.MySQL UPDATE JOIN構文MySQL では、UPDATE ステートメントでJOIN句...

MySQL フラッシュバック ツール binlog2sql の詳細なインストールと設定のチュートリアル

概要binlog2sql は、Python で開発されたオープンソースの MySQL Binlog ...

CSS で TikTok テキスト揺れエフェクトを実装する例

日々の開発において、フロントエンドの学生はアニメーションやデザインについてよく議論します。デザイナー...

WiFi 開発 | WiFi ワイヤレス テクノロジーの紹介

目次WiFiワイヤレステクノロジーの紹介1. WiFiテクノロジーの概要2. ESP8266の紹介W...

CSS における px、em、rem、%、vw、vh 単位の違いの詳細な説明

1.ピクセルpx はピクセルの略語で、画面解像度に対する相対的な長さの単位です。 2. えむ参照は親...

Vue の el-table は自動天井効果を実現します (固定をサポート)

目次序文実装のアイデア効果:使用:メインソースコード:序文多くのケースを見た結果、単純な観点からは、...

DockerコンテナのIPアドレスを表示する方法

私はずっとDockerにはIPアドレスがないと思っていました。実はDockerのネットワークテンプレ...