NginxにおけるRewriteのリダイレクト設定と実践の詳しい解説

NginxにおけるRewriteのリダイレクト設定と実践の詳しい解説

1: アドレス書き換えとア​​ドレス転送の意味を理解する。

アドレス書き換えとア​​ドレス転送は異なる概念です。

アドレス書き換えは、アドレスの標準化を実現することです。たとえば、アドレスバーに www.baidu.com と入力できます。また、www.baidu.cn と入力することもできます。最終的には、www.baidu.com に書き換えられます。ブラウザのアドレスバーにも www.baidu.com が表示されます。

アドレス転送: ネットワーク データ転送中にデータ パケットがルーターまたはブリッジに到達した後、デバイスがパケット アドレスを確認し、データを最も近いローカル エリア ネットワークに転送するプロセスを指します。

したがって、アドレス書き換えとア​​ドレス転送には次のような違いがあります。

1. アドレス書き換えはブラウザ内のアドレスを変更し、ブラウザの最新アドレスに書き換えます。アドレス転送ではブラウザのアドレスは変更されません。
2. アドレス書き換えでは 2 つのリクエストが生成されますが、アドレス転送では 1 つのリクエストのみが生成されます。
3. アドレス転送は通常、同じサイト プロジェクト内で行われますが、アドレス書き換えは制限されません。
4. アドレス転送はアドレスリダイレクトよりも高速です。

2: 書き換え命令の使用を理解する

このディレクティブは、正規表現を使用して URI を変更するために使用されます。 1 つ以上のディレクティブが同時に存在できます。 URL を順番に照合して処理する必要があります。

このディレクティブは、server ブロックまたは location ブロックで設定できます。基本的な構文構造は次のとおりです。

正規表現の置換を書き換える [フラグ];

rewrite の意味: この命令は URL 書き換えを実装するために使用されます。
regex の意味: URI を一致させるために使用される正規表現。
replacement: 正規表現に一致したコンテンツを replacement に置き換えます。
旗:旗マーク。

フラグには次の値があります。

  • last: このルールが一致した後、新しい場所 URI ルールとの一致を続行します。 (あまり使われない)
  • break: このルールは一致すると終了し、それ以上のルールは一致しなくなります (一般的には使用されません)。
  • リダイレクト: 302 一時リダイレクトを返し、ブラウザ アドレスに新しい URL アドレスが表示されます。
  • permanent: 301 永続リダイレクトを返します。ブラウザのアドレスに新しい URL アドレスが表示されます。

たとえば、次の例をご覧ください。

書き換え^/(.*) http://www.baidu.com/$1 永久的;

例:
rewrite は固定キーワードであり、書き換え一致ルールの実行を開始することを意味します。
正規表現は^/(.*)です。 これは、完全なドメイン名とそれに続くパス アドレスに一致する正規表現です。
置換は http://www.baidu.com/$1 です。ここで、$1 は正規表現部分 () の内容です。一致した場合にジャンプする URL。
フラグは永続的であり、永続的なリダイレクト、つまりアドレス http://www.baidu.com/$1 にジャンプすることを意味します。

これをシミュレートする簡単なデモをやってみましょう:

1. テスト プロジェクトには app.js があります。コードは次のとおりです。

const Koa = require('koa');
const app = new Koa();

const ルーター = require('koa-router')();

// ルートを追加 router.get('/', ctx => {
 ctx.body = '<h1>インデックスページへようこそ</h1>';
});

router.get('/home', ctx => {
 ctx.body = '<h1>ホームページへようこそ</h1>';
});

router.get('/404', ctx => {
 ctx.body = '<h1>404...</h1>'
});

// ルーティングミドルウェアをロードします。app.use(router.routes());

app.listen(3001, () => { 
 console.log('サーバーはhttp://localhost:3001で実行されています');
});

次に、コマンド ラインで node app.js を実行し、ブラウザーで http://localhost:3001 にアクセスして対応するページにアクセスできます。しかし、今はノード プロジェクトをローカルの nginx サーバーにデプロイしたいと考えています。 nginx のインストールについては私の記事をお読みください。次に、ドメイン名を使用してプロジェクトにアクセスしたいので、nginx.conf で設定する必要があります。

/usr/local/etc/nginx をコピーします

次に、sudo open /usr/local/etc/nginx/nginx.conf -a 'sublime text' コマンドを使用して nginx.conf を開き、次のように設定します。

ワーカープロセス 1;

イベント {
  ワーカー接続 1024;
}
http {
  mime.types を含めます。
  デフォルトタイプ アプリケーション/オクテットストリーム;

  ファイル送信オン;
  #tcp_nopush オン;

  #キープアライブタイムアウト 0;
  キープアライブタイムアウト65;

  #gzip オン;

  サーバー{
   聞く 8081;
   server_name ローカルホスト;
   位置 / {
    ルートhtml;
    インデックス index.html index.htm; 
   }
   エラーページ 500 502 503 504 /50x.html;
   場所 = /50x.html {
    ルートhtml;
   }
  }
  サーバー{
   聞く 8088;
   サーバー名 xxx.abc.com;
   位置 / {
    プロキシパス http://127.0.0.1:3001;
    書き換え^/(.*) http://www.baidu.com 永久的;
   }
  }
}

上記のコードに示されているように、リスニング ポート番号は 8088 で、server_name 構成は xxx.abc.com に設定されています。次に、http://xxx.abc.com:8088/ にアクセスすると、まず http://127.0.0.1:3001 の下のノードに対応するページにリバース プロキシされます。リバース プロキシが完了すると、rewrite を使用して Baidu ページにリダイレクトされます。上記の設定が完了したら、nginx サーバーを再起動する必要があります。次のコマンドを使用します。

次に、ブラウザで http://xxx.abc.com:8088/ にアクセスすると、次の図に示すように実行されます。まず、http://xxx.abc.com:8088/ (301) に永続的にリダイレクトし、次に Baidu (307) にアクセスし、一時的に Baidu ページにリダイレクトし、最後に Baidu ページのアドレスを読み込みます。次のデモをご覧ください。

しかし、たとえば nginx の設定後に permanent を redirect に変更すると、rewrite ^/(.*) http://www.baidu.com redirect; となり、302 一時リダイレクトになります。以下のように表示されます。

3: if命令を理解する

このディレクティブは、条件判断をサポートし、条件判断の結果に基づいて異なる nginx 構成を選択するために使用されます。このディレクティブは、server ブロックまたは location ブロックで設定できます。その文法構造は次のとおりです。

if (条件) {
 // ....
}

条件は、true/false の意味を持つブール値です。

Rewrite ディレクティブで使用できるグローバル変数は次のとおりです。

1. $args: この変数には、リクエスト URL 内のリクエスト指示が格納されます。たとえば、http://127.0.0.1:3001?arg1=value1&arg2=value2
「arg1=値1&arg2=値2」。
2. $content_length: この変数は、リクエスト ヘッダーの Content-length フィールドを格納します。
3. $content_type: この変数は、リクエスト ヘッダーの Content-type フィールドを格納します。
4. $document_root: この変数には、現在のリクエストのルート パスが格納されます。
5. $document_uri: この変数にはリクエストの現在の URI が格納されますが、リクエストの指示は含まれません。たとえば、http://xxx.abc.com/home/1?arg1=value1&
arg2=value2 の "/home/1"
6. $host: 変数には、要求された URL のホスト部分 (http://xxx.abc.com:8080/home の xxx.abc.com など) が格納されます。
7. $http_host: この変数と$hostの唯一の違いは、ポート番号が含まれていることです。たとえば、上記の場合はxxx.abc.com:8080です。
8. $http_user_agent: この変数にはクライアントのプロキシ情報が格納されます。
9. $http_cookie、この変数はクライアントのクッキー情報を格納します。
10. $remote_addr この変数にはクライアントのアドレスが格納されます。
11. $remote_port この変数には、クライアントがサーバーとの接続を確立するために使用するポート番号が格納されます。
12. $remote_user 変数にはクライアントのユーザー名が格納されます。
13. $request_body_file変数には、バックエンドサーバーに送信されたローカルファイルリソースの名前が格納されます。
14. $request_method 変数には、「GET」、「POST」などのクライアントのリクエストメソッドが格納されます。
15. $request_filename 変数には、現在要求されているリソース ファイルのパス名が格納されます。
16. $request_uri 変数には現在のリクエストの URI が格納され、リクエストの指示が含まれます。
17. $query_string は変数 $args と同じ意味を持ちます。
18. $scheme 変数には、「http」、「https」など、クライアント要求で使用されるプロトコルが格納されます。
19. $server_protocol 変数には、「HTTP/1.0」、「HTTP/1.1」などのクライアント要求プロトコルのバージョンが格納されます。
……など

正規表現の基本的な構文は次のとおりです。

1. 変数を一致させる

「~」は、一致処理で大文字と小文字が区別されることを意味します。
「~*」は、一致処理で大文字と小文字が区別されないことを意味します。
'!~' '~' の一致が失敗した場合、条件は真になります。
'!~*' '~*' の一致が失敗した場合、条件は真になります。

例えば:

$http_user_agent の場合:
 // コードの意味: $http_user_agent 値に MSIE 文字列が含まれているかどうか。含まれている場合は true、含まれていない場合は false
}

2. 要求されたファイルが存在するかどうかを確認する

'-f' 要求されたファイルが存在する場合、この条件は真になります。
'!-f' ファイルのディレクトリが存在し、ファイルが存在しない場合は true を返します。ファイルもディレクトリも存在しない場合は、これは false になります。
要求されたディレクトリが存在しないが、要求されたファイルが存在する場合も、これは false になります。

if (-f $リクエストファイル名) {
 // 要求されたファイルが存在するかどうかを確認します}

if (!-f $リクエストファイル名) {
 // 要求されたファイルが存在しないかどうかを確認します}

3. '-d' と '!-d' を使用して、要求されたディレクトリが存在するかどうかを確認します。

'-d' を使用すると、要求されたディレクトリが存在する場合に true を返します。それ以外の場合は false を返します。
'!-d' を使用すると、要求されたディレクトリが存在しないが、要求の親ディレクトリが存在する場合は true を返します。親ディレクトリが存在しない場合は、false を返します。その他の構文もいくつかありますが、ここでは詳しく説明しません。

ここで、if ディレクティブを使用して nginx に判断を追加します。たとえば、http://xxx.abc.com:8080/home にアクセスすると、$host = 'xxx.abc.com' の場合はリダイレクトされます。nginx の構成コードは次のとおりです。

サーバー{
 聞く 8088;
 サーバー名 xxx.abc.com;
 位置 / {
  プロキシパス http://127.0.0.1:3001;
  $host = 'xxx.abc.com'の場合{
   書き換え^/(.*) http://www.cnblogs.com リダイレクト;
  }
 }
}

上記のように nginx を設定すると、http://xxx.abc.com:8088 にアクセスすると、http://www.cnblogs.com にリダイレクトされます。

例えば、ユーザーエージェントが携帯電話からアクセスされた場合、特定のページに直接ジャンプするか、if 判断を使用するかなど、より多くの判断が行われます。例えば:

if ( $http_user_agent ~* "(Android)|(iPhone)|(モバイル)|(WAP)|(UCWEB)" ){
 書き換え^/$ http://www.cnblogs.com 永久;
}

4: アンチホットリンクとnginxの設定を理解する

アンチホットリンクとは何ですか?ホットリンクとは、画像リンクを盗むこと、つまり他人の写真を盗んで自分のサーバーで使用することと理解できます。また、アンチホットリンクとは、他人が私の写真を盗むのを防ぐことと理解できます。

アンチホットリンクの実装原則: クライアントがサーバーからリソースを要求すると、ネットワーク帯域幅を削減し、応答時間を改善するために、サーバーは通常、すべてのリソースを一度にクライアントに完全に送信しません。たとえば、Web ページをリクエストすると、まず Web ページのテキスト コンテンツが返されます。クライアント ブラウザーは、テキストを解析する過程で画像があることを検出すると、再度サーバーに画像リソースのリクエストを開始し、サーバーは保存されている画像リソースをクライアントに送信します。しかし、この画像が別のサイトのサーバーにリンクされていたらどうなるでしょうか? たとえば、私のプロジェクトでは、Taobao から画像を参照しました。その後、Web サイトがリロードされると、Taobao サーバーにリクエストが送信され、Taobao サーバーに負荷がかかる可能性があります。つまり、これはホットリンクです。したがって、ホットリンク防止を実装する必要があります。

ホットリンク防止を実装する: http プロトコルのリクエスト ヘッダーの Referer ヘッダー フィールドを使用して、現在アクセスされている Web ページまたはファイルのソース アドレスを決定します。このヘッダー フィールドの値を通じて、対象リソースへのアクセスの送信元アドレスを検出できます。対象ソースアドレスが自社サイトのURLでない場合は、ホットリンクを防止するためのブロッキング対策を講じます。ただし、Referer ヘッダー フィールドの値は変更される可能性があることに注意してください。したがって、この方法ではホットリンクを完全に防止することはできません。

Nginx サーバーの Rewrite 機能を使用して、ホットリンク防止を実装します。

Nginx には、valid_referers ディレクティブがあります。このディレクティブを使用すると、Referer ヘッダー フィールドの値を取得し、その値に基づいて Nginx グローバル変数 $invalid_referer に値を割り当てることができます。 Referer ヘッダー フィールドに valid_referers ディレクティブに一致する値が含まれていない場合、$invalid_referer 変数に値 1 が割り当てられます。

valid_referers ディレクティブの基本的な構文は次のとおりです。

valid_referers なし | ブロック | server_names | 文字列

none: Referer ヘッダー フィールドが存在しないことを検出します。
ブロック: Referer ヘッダー フィールドの値がファイアウォールまたはプロキシ サーバーによって削除または偽装されている状況を検出します。この場合、このヘッダー フィールドの値は「http://」または「https://」で始まりません。

server_names: 1 つ以上の URL を設定し、Referer ヘッダー フィールドの値が URL の 1 つであるかどうかを確認します。

したがって、valid_referers ディレクティブと $invalid_referer 変数があれば、Rewrite 関数を通じてホットリンク防止を実装できます。
以下に 2 つのソリューションを紹介します。1 つ目は、要求されたリソースの種類に基づくものです。 2番目: リクエストディレクトリに基づきます。

1. 次の表は、要求されたファイルの種類に基づいたアンチホットリンク構成を示しています。

サーバー{
 8080を聴く;
 サーバー名 xxx.abc.com
 場所 ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$ {
  valid_referers なし ブロックされました www.xxx.com www.yyy.com *.baidu.com *.tabobao.com;
  ($invalid_referer) の場合 {
   書き換え^/ http://www.xxx.com/images/forbidden.png;
  }
 }
}

上記の基本構成では、ネットワーク接続を使用して、サフィックスが gif、jpg、または png の画像リソース、サフィックスが swf または flv のメディア リソース、サフィックスが rar または zip の圧縮リソースを要求するときに、Referer ヘッダー フィールドが valid_referers ディレクティブに準拠していないことが検出された場合、その要求はこのサイトのリソースに対するものではないことを意味します。

location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$ この設定は、ホットリンク防止のファイルタイプを設定することを意味します。

valid_referers none blocked www.xxx.com www.yyy.com *.baidu.com *.tabobao.com; これは、ファイルリンクを許可するドメイン名のホワイトリスト、つまりホワイトリストとして理解できます。要求されたリソースファイルがこれらのドメイン名で始まっていない場合、要求されたリソースファイルはこのドメインの下にある要求ではないことを意味するため、ホットリンクと判断できます。したがって、リクエストがこのドメインにない場合は、Rewrite を使用して画像 http://www.xxx.com/images/forbidden.jpg にリダイレクトされます。たとえば、この画像が x またはその他のロゴである場合、他の Web サイトは画像にアクセスできなくなります。

2. リクエストディレクトリに基づいてアンチホットリンクを実装するための構成は次のとおりです。

サーバー{
 8080を聴く;
 サーバー名 xxx.abc.com
 場所 /file/ {
  ルート /server/file/;
  valid_referers なし ブロックされました www.xxx.com www.yyy.com *.baidu.com *.tabobao.com;
  ($invalid_referer) の場合 {
   書き換え^/ http://www.xxx.com/images/forbidden.png;
  }
 }
}

Nginx における Rewrite のリダイレクト設定と実践について詳細に解説したこの記事はこれで終了です。より関連性の高い Nginx Rewrite リダイレクトコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Nginx でのドメイン名の 301 リダイレクト方法の概要
  • nginx 設定 URL リダイレクト - リバース プロキシの詳細な説明
  • Nginxのリダイレクト機能の詳しい説明
  • nginxディレクトリパスをリダイレクトする方法
  • nginxアドレスをリダイレクトする方法
  • Nginx リダイレクト設定例
  • Nginx 301 リダイレクト設定の詳細な説明
  • Nginx サーバー リダイレクト構成リファレンス ガイド
  • Nginxがリダイレクトするときにドメイン名を取得する方法の例

<<:  mysql コマンドライン スクリプトの実行例

>>:  JavaScript 手ぶれ補正のケーススタディ

推薦する

HTML テーブル マークアップ チュートリアル (30): セルの暗い境界線の色属性 BORDERCOLORDARK

セルでは、暗い境界線の色を個別に定義できます。基本的な構文<TD ボーダーコロダーク=colo...

動的なデジタル時計を実装するJavaScript

この記事では、JavaScriptで動的なデジタル時計を実装するための具体的なコードを参考までに紹介...

入力ボックスのプレースホルダーアニメーションと入力検証を実現する純粋なCSS

さらに興味深いコンテンツについては、https://github.com/abc-club/free...

Nginx リバースプロキシの例の詳細な説明

1. リバースプロキシの例1 1. 効果を達成する(1)ブラウザを開き、www.123.comと入力...

Docker イメージに基づいて Go プロジェクトをデプロイする方法と手順

知識への依存Go クロスコンパイルの基礎Dockerの基礎Dockerfileカスタムイメージの基本...

Nginx がリクエストを処理する際のマッチングルールの詳細な分析

nginx はリクエストを受信すると、まず server_name でサーバーを照合し、次にサーバー...

CSS3で実装された読み込みアニメーション

成果を達成する実装コード <h1>123WORDPRESS.COM</h1>...

MySQL で自動インクリメントシーケンスを実装するためのサンプルコード

1. シーケンステーブルを作成する テーブル `sequence` を作成します ( `name` ...

docker の実行に必要な権限の分析

Docker を実行するには root 権限が必要です。非 root ユーザーに docker コマ...

HTML で #include ファイルを使用する例

a.htmとb.htmの2つのファイルがあります。同じディレクトリ内のa.htmの内容は次のとおりで...

Linux での MySQL 5.6.24 (バ​​イナリ) 自動インストール スクリプト

この記事では、Linux環境でのmysql5.6.24自動インストールスクリプトコードを参考までに共...

JavaScript イベント委任 (プロキシ) の使用例の詳細

目次導入例: イベントの委任記述方法1: イベント委譲書き方2: 各子要素がイベントをバインドする例...

追加、削除、変更、クエリを実行するための JS 操作オブジェクト配列のサンプルコード

1. はじめに最近、私は友人が JSON 配列を追加、削除、変更するための簡単なページを作成するのを...

Vueのウォッチリスナーの使い方を説明する記事

目次リスナーウォッチ形式リスナーを設定します。要約するリスナーウォッチ関数名は、リッスンする要素の名...