proxy_intercept_errors と recursive_error_pages を使用して複数の 302 をプロキシする 302 は、HTTP プロトコルで頻繁に使用されるステータス コードです。これは複数のリダイレクト方法の 1 つであり、その意味は「一時的に移動」と解釈されることがよくあります。ちなみに、302 は実際には誤用 (303 や 307 と混在) によりよく使用されます。HTTP/1.1 では、そのセマンティクスは「Found」です。 302 は、非常に明白な場合もあれば、非常に隠れている場合もあります。最も単純なケースは、ブラウザに URL A を入力すると、ブラウザのアドレス バーが自動的に B にジャンプし、Web ページが開く場合です。この状況は 302 である可能性が最も高くなります。 Web ページに埋め込まれたプレーヤーでは、より微妙な状況が発生することがよくあります。例えば、Youku の動画再生ページを開くと、パケットをキャプチャして観察すると、302 の影が見つかることが多いです。ただし、これらの URL はブラウザで直接開かれないため、ブラウザのアドレス バーには変更が表示されません。もちろん、これらの特定の URL を具体的に選択してブラウザのアドレス バーにコピーすると、引き続き確認できます。 Youkuについては前の段落で触れました。実際、ほとんどのオンライン ビデオ ウェブサイトは現在 302 を使用しています。その理由は非常に単純です。ビデオ ウェブサイトは一般にトラフィックが多く、CDN を使用します。唯一の違いは、自分で構築した CDN を使用するか、商用 CDN を使用するかです。また、302 のリダイレクト セマンティクス (繰り返しますが、302 のセマンティクスは広く誤用されています。302 を使用する場合は、おそらく 303 または 307 を使用する必要がありますが、これについては後で詳しく説明しません) により、CDN のスケジュールとうまく組み合わせることができます。 例を見てみましょう。NetEase のビデオ再生ページを開き、パッケージを取得して、302 ステータスの URL を見つけます。例えば:
これをブラウザのアドレス バーにコピーすると、アドレス バーがすぐに別の URL に変わります。この URL は不確かで、次のようなものである可能性があります。
curl ツールを使用すると、プロセス全体がより明確に表示されます。 カール -I "http://flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -L HTTP/1.1 302 一時的に移動しました サーバー: nginx 日付: 2014 年 8 月 25 日 (月) 14:49:43 GMT コンテンツタイプ: text/html コンテンツの長さ: 154 接続: キープアライブ NG: CCN-SW-1-5L2 X-Mod名: GSLB/3.1.0 場所: http://119.134.254.9/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 HTTP/1.1 302 一時的に移動しました サーバー: nginx 日付: 2014 年 8 月 25 日 (月) 14:49:41 GMT コンテンツタイプ: text/html コンテンツの長さ: 154 接続: キープアライブ X-Mod-Name: Mvod-Server/4.3.3 場所: http://119.134.254.7/cc89fdac00000000-1408983581-2095617481/data4/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 NG: CHN-SW-1-3Y1 HTTP/1.1 200 OK サーバー: nginx 日付: 2014 年 8 月 25 日 (月) 14:49:41 GMT コンテンツタイプ: video/mp4 コンテンツの長さ: 3706468 最終更新日: 2014年8月25日 (月) 00:23:50 GMT 接続: キープアライブ キャッシュ制御: キャッシュなし ETag: "53fa8216-388e64" NG: CHN-SW-1-3g6 X-Mod-Name: Mvod-Server/4.3.3 受け入れ範囲: バイト ご覧のとおり、プロセス中に 302 エラーが 2 つ発生しました。 この例は今は置いておいて、別の重要な用語である「プロキシ」について話しましょう。リーダーの中には 302 タイプのリーダーもいれば、プロキシ タイプのリーダーもいるとよく冗談で言われます。 302 タイプのリーダーは、タスクが自分の手に渡るとすぐにそれを他の人に引き継ぎますが、プロキシ タイプのリーダーはタスクに参加し、すべてを完了します。 上記の例に戻ると、URL にアクセスするときに複数の 302 がある場合、これらすべての 302 を途中で非表示にする Nginx を使用したプロキシを設計する必要がある場合はどうすればよいでしょうか。 1. オリジナルプロキシ Nginx 自体は優れたプロキシ サーバーであることはわかっています。したがって、まず、サーバー IP が 192.168.109.128 (テスト仮想マシンの 1 つ) である Nginx フォワード プロキシを設定しましょう。 初期設定は次のように簡略化されます。 サーバー{ 聞く 80; 位置 / { rewrite_by_lua ' ngx.exec("/proxy-to" .. ngx.var.request_uri) '; } 場所 ~ /proxy-to/([^/]+)(.*) { proxy_pass http://$1$2$is_args$クエリ文字列; } } 達成される機能は、
プロキシにアクセスすると、xxxxxx で表される実際のサーバーにプロキシされます。 テスト結果は次のとおりです。 カール -I "http://192.168.109.128/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -L HTTP/1.1 302 一時的に移動しました サーバー: nginx/1.4.6 日付: 2014 年 8 月 25 日 (月) 14:50:54 GMT コンテンツタイプ: text/html コンテンツの長さ: 154 接続: キープアライブ NG: CCN-SW-1-5L2 X-Mod名: GSLB/3.1.0 場所: http://183.61.140.24/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 HTTP/1.1 302 一時的に移動しました サーバー: nginx 日付: 2014 年 8 月 25 日 (月) 14:50:55 GMT コンテンツタイプ: text/html コンテンツの長さ: 154 接続: キープアライブ X-Mod-Name: Mvod-Server/4.3.3 場所: http://183.61.140.20/540966e500000000-1408983655-236096587/data1/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 NG: CHN-ZJ-4-3M4 HTTP/1.1 200 OK サーバー: nginx 日付: 2014 年 8 月 25 日 (月) 14:50:55 GMT コンテンツタイプ: video/mp4 コンテンツの長さ: 3706468 最終更新日: 2014年8月25日 (月) 00:31:03 GMT 接続: キープアライブ キャッシュ制御: キャッシュなし ETag: "53fa83c7-388e64" NG: CHN-ZJ-4-3M4 X-Mod-Name: Mvod-Server/4.3.3 受け入れ範囲: バイト プロキシが使用されているにもかかわらず、プロセスは元のアクセスと変わらないことがわかります。アクセスプロセスは次のとおりです。
Nginxがリクエストをプロキシすると
後者はすぐに 302 を返すため、プロキシとしての Nginx は 302 をクライアントに返し、クライアントはリクエストを再開して、前の 302 を繰り返します。これは問題を示しています。Nginx のプロキシのバックエンドが 302 を返すと、クライアントは Nginx プロキシから切断され、Nginx は完全なプロキシの役割を果たすことができなくなります。 2. 最初の改訂 構成ファイルを次のように変更します。 サーバー{ 聞く 80; 位置 / { rewrite_by_lua ' ngx.exec("/proxy-to" .. ngx.var.request_uri) '; } 場所 ~ /proxy-to/([^/]+)(.*) { proxy_pass http://$1$2$is_args$クエリ文字列; エラーページ 302 = @error_page_302; } 場所 @error_page_302 { rewrite_by_lua ' ローカル _, _, アップストリーム http_location = string.find(ngx.var.upstream_http_location, "^http:/(.*)$") ngx.header["zzzz"] = "/proxy-to" .. アップストリームhttpの場所 ngx.exec("/proxy-to" ..upstream_http_location); '; } } 上記との違いは、error_page が使用されていることです。その目的は、プロキシ バックエンドが 302 を返すことがわかった場合、この 302 の宛先場所をクライアントに直接返すのではなく、プロキシに継続することです。そして、このロジックには再帰の意味が含まれており、最終的に 200 のアドレスに戻るまで 302 を追跡します。テスト結果は次のとおりです。 カール -I "http://192.168.109.128/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -L HTTP/1.1 302 一時的に移動しました サーバー: nginx/1.4.6 日付: 2014 年 8 月 25 日 (月) 15:01:17 GMT コンテンツタイプ: text/html コンテンツの長さ: 154 接続: キープアライブ NG: CCN-SW-1-5L2 X-Mod名: GSLB/3.1.0 場所: http://183.61.140.24/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 HTTP/1.1 302 一時的に移動しました サーバー: nginx 日付: 2014 年 8 月 25 日 (月) 15:01:17 GMT コンテンツタイプ: text/html コンテンツの長さ: 154 接続: キープアライブ X-Mod-Name: Mvod-Server/4.3.3 場所: http://183.61.140.20/a90a952900000000-1408984277-236096587/data1/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 NG: CHN-ZJ-4-3M4 HTTP/1.1 200 OK サーバー: nginx 日付: 2014 年 8 月 25 日 (月) 15:01:17 GMT コンテンツタイプ: video/mp4 コンテンツの長さ: 3706468 最終更新日: 2014年8月25日 (月) 00:31:03 GMT 接続: キープアライブ キャッシュ制御: キャッシュなし ETag: "53fa83c7-388e64" NG: CHN-ZJ-4-3M4 X-Mod-Name: Mvod-Server/4.3.3 受け入れ範囲: バイト この変更はまだ成功していないことがわかります。 なぜ?分析の結果、@error_page_302 の場所にヘッダー印刷ステートメントを追加しましたが、テストではヘッダーが印刷されず、プロセスが @error_page_302 の場所に入っていないことがわかります。 その理由は エラーページ 302 = @error_page_302; デフォルトでは、error_page はこのプロセスの戻りコードです。プロキシとして、この処理では、上流サーバーの応答が正常に転送されている限り、ステータス コードは 200 になるはずです。つまり、実際に確認する必要があるのは、プロキシ自体によって返されるステータス コードではなく、プロキシのバックエンド サーバーによって返されるステータス コードです。 Nginx wiki を見ると、proxy_intercept_errors ディレクティブはまさにこれを実行します。 構文: proxy_intercept_errors on | off; デフォルト: proxy_intercept_errors をオフ; コンテキスト: http、サーバー、場所 300 以上のコードを持つプロキシ応答をクライアントに渡すか、error_page ディレクティブを使用して処理するために nginx にリダイレクトするかを決定します。 3. 2回目の改訂 サーバー{ 聞く 80; proxy_intercept_errors がオン; 位置 / { rewrite_by_lua ' ngx.exec("/proxy-to" .. ngx.var.request_uri) '; } 場所 ~ /proxy-to/([^/]+)(.*) { proxy_pass http://$1$2$is_args$クエリ文字列; エラーページ 302 = @error_page_302; } 場所 @error_page_302 { rewrite_by_lua ' ローカル _, _, アップストリーム http_location = string.find(ngx.var.upstream_http_location, "^http:/(.*)$") ngx.header["zzzz"] = "/proxy-to" .. アップストリームhttpの場所 ngx.exec("/proxy-to" ..upstream_http_location); '; } } 以前の変更と比較すると、唯一の違いは proxy_intercept_errors ディレクティブが追加されたことです。テスト結果は次のとおりです。 カール -I "http://192.168.109.128/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -L HTTP/1.1 302 一時的に移動しました サーバー: nginx/1.4.6 日付: 2014 年 8 月 25 日 (月) 15:05:54 GMT コンテンツタイプ: text/html コンテンツの長さ: 160 接続: キープアライブ zzzz: /proxy-to/183.61.140.24/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 今回はさらに魔法のようです。302 ステータスを直接返して、それ以上ジャンプしません。 問題は、最初の 302 リクエストは @error_page_302 に正常に入力されるものの、後続の error_page 命令が機能しないことです。つまり、error_page はバックエンドから最初に返されたステータス コードのみをチェックし、後続のバックエンド ステータス コードはチェックし続けます。 情報を確認します。このとき、別のコマンド recursive_error_pages が役立ちます。 4. 第三次改訂 サーバー{ 聞く 80; proxy_intercept_errors がオン; recursive_error_pages オン; 位置 / { rewrite_by_lua ' ngx.exec("/proxy-to" .. ngx.var.request_uri) '; } 場所 ~ /proxy-to/([^/]+)(.*) { proxy_pass http://$1$2$is_args$クエリ文字列; エラーページ 302 = @error_page_302; } 場所 @error_page_302 { rewrite_by_lua ' ローカル _, _, アップストリーム http_location = string.find(ngx.var.upstream_http_location, "^http:/(.*)$") ngx.header["zzzz"] = "/proxy-to" .. アップストリームhttpの場所 ngx.exec("/proxy-to" ..upstream_http_location); '; } } 前回と比較すると、recursive_error_pages on 命令のみが追加されました。テスト結果は次のとおりです。 カール -I "http://192.168.109.128/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -L HTTP/1.1 200 OK サーバー: nginx/1.4.6 日付: 2014 年 8 月 25 日 (月) 15:09:04 GMT コンテンツタイプ: video/mp4 コンテンツの長さ: 3706468 接続: キープアライブ zzzz: /proxy-to/14.18.140.83/f48bad0100000000-1408984745-236096587/data6/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 最終更新日: 2014年8月25日 (月) 00:21:07 GMT キャッシュ制御: キャッシュなし ETag: "53fa8173-388e64" NG: CHN-MM-4-3FE X-Mod-Name: Mvod-Server/4.3.3 受け入れ範囲: バイト Nginx が最終的に 200 を正常に返したことがわかります。この時点で、Nginx は実際にプロキシの役割を果たし、リクエストの複数の 302 リンクを隠し、クライアントに 1 つの最終結果のみを返します。 5. まとめ 要約すると、proxy_pass、error_page、proxy_intercept_errors、および recursive_error_pages 命令を一緒に使用することで、クライアントからのリクエストのリダイレクトの詳細を隠し、ステータス コード 200 の最終結果をユーザーに直接返すことができます。 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: JavaScript ステートメントの一般的な for ループの詳細な説明
>>: シェルでパスワードなしでMySQLデータベースに素早くログインする方法
前: マークアップ言語 - フレーズ要素 オリジナルソース 第 7 章 アンカーHTML のリンクの...
Mysql は人気があり、使いやすいデータベース ソフトウェアです。以下は、mysql の無料インス...
この記事では、例を使用して MySQL ビューの管理ビュー操作について説明します。ご参考までに、詳細...
この記事の例では、ショッピングカート機能を実装するためのvuexの具体的なコードを参考までに共有して...
目次序文:特定の操作ステップ1: プレハブを準備するステップ2: オブジェクトプールを初期化するステ...
1. データベースの文字セットを確認するデータベースの文字セットは、Linux で設定された環境変数...
目次1. axioの基本的な使い方2. クロスドメインの問題を解決するには? 3. パッケージ4. ...
目次1. データベースのマスター/スレーブ分類: 2. MySQL マスタースレーブの紹介3. マス...
ant-design-vue は Ali iconfont icons の使用をカスタマイズします\...
複合インデックス (結合インデックスとも呼ばれます) は、複数の列に対して作成されるインデックスです...
データ共有プロトタイプにはどのようなデータを書き込む必要がありますか?共有する必要があるデータはプロ...
始める前に、process.env.NODE_ENV にはデフォルトで開発と本番の 2 つの状態しか...
目次関数呼び出しの最適化関数呼び出しの最適化MySQL 関数は、内部的に決定論的または非決定論的とし...
1. どのように構築しますか? es5 でクラスを構築する一般的な方法を確認しましょう。まず、es5...
<br />帯域幅の増加に伴い、Web ページ上のオブジェクトも増えているため、Web ...