Nginxでは、次のようにURLをリダイレクトしようとしています。
http://example.com/some/path -> http://192.168.1.24
ユーザーはブラウザに元のURLを表示します。ユーザーがリダイレクトされた後、/section/index.html
へのリンクをクリックすると、リダイレクトにつながるリクエストを実行します
http://example.com/some/path/section/index.html -> http://192.168.1.24/section/index.html
再び元のURLを保持します。
私たちの試みには、プロキシと書き換えルールを使用したさまざまなソリューションが含まれています。以下は、ソリューションに最も近い構成を示しています(これはexample.com
WebサーバーのWebサーバー構成です)。ただし、これにはまだ2つの問題があります。
http://192.168.1.24
に/some/path
が含まれているため、必要なページを提供できないため、正しく書き換えられません。ページが提供された後にリンクにカーソルを合わせると、URLに/some/path
がありません
server {
listen 80;
server_name www.example.com;
location /some/path/ {
proxy_pass http://192.168.1.24;
proxy_redirect http://www.example.com/some/path http://192.168.1.24;
proxy_set_header Host $Host;
}
location / {
index index.html;
root /var/www/example.com/htdocs;
}
}
example.com
のWebサーバー構成を変更するだけのソリューションを探しています。 192.168.1.24
(Nginxも)の構成を変更できますが、example.com
を介してアクセスがプロキシされる数百の異なるサーバーに対してこの設定を繰り返す必要があるため、これを避けたいと思います。
まず、ロケーションブロック内でroot
ディレクティブを使用しないでください。これは悪い習慣です。この場合は問題ではありません。
2番目のロケーションブロックを追加してみてください。
location ~ /some/path/(?<section>.+)/index.html {
proxy_pass http://192.168.1.24/$section/index.html;
proxy_set_header Host $Host;
}
これは、/ some/path /の後のindex.htmlの前の部分を$ section変数にキャプチャし、proxy_pass宛先を設定するために使用されます。必要に応じて、正規表現をより具体的にすることができます。
proxy_pass
ディレクティブではURI部分を使用する必要があります。また、proxy_redirect
ディレクティブの順序引数を混同しているため、おそらくまったく必要ありません。 Nginxには、このディレクティブの適切なデフォルトがあります。
この場合、あなたのlocation
ブロックは本当に簡単です:
location /some/path/ {
proxy_pass http://192.168.1.24/;
# note this slash -----------^
proxy_set_header Host $Host;
}
次の設定を使用して、フロントエンドの/some/path/
とバックエンドの/
を100%シームレスにマッピングできます。
これがこれまでの唯一の回答であり、ブラウザから正しいHTTP Referer
ヘッダーが送信された場合、404 Not Found
エラーを生成する絶対パスもシームレスに処理するので、これらのgifはすべてロードせずに引き続きロードする必要があります。基になるHTMLを変更する必要があります(コストがかかるだけでなく、デフォルトでコンパイルされていない追加のモジュールがないとサポートされません)。
location /some/path/ {
proxy_pass http://192.168.1.24/; # note the trailing slash!
}
location / {
error_page 404 = @404;
return 404; # this would normally be `try_files` first
}
location @404 {
add_header Vary Referer; # sadly, no effect on 404
if ($http_referer ~ ://[^/]*(/some/path|/the/other)/) {
return 302 $1$uri;
}
return 404 "Not Found\n";
}
https://github.com/cnst/StackOverflow.cnst.nginx.conf リポジトリ内で コンセプトの完全な証明とminimal-viable-product を見つけることができます。
以下は、すべてのEdgeケースが機能しているように見えることを確認するためのテスト実行です。
curl -v -H 'Referer: http://example.su/some/path/page.html' localhost:6586/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location
> GET /and/more.gif HTTP/1.1
> Referer: http://example.su/some/path/page.html
< HTTP/1.1 302 Moved Temporarily
< Location: http://localhost:6586/some/path/and/more.gif
< Vary: Referer
curl -v localhost:6586/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location
> GET /and/more.gif HTTP/1.1
< HTTP/1.1 404 Not Found
curl -v localhost:6586/some/path/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location -e uri
> GET /some/path/and/more.gif HTTP/1.1
< HTTP/1.1 200 OK
request_uri: /and/more.gif
追伸マップするさまざまなパスがたくさんある場合は、$http_referer
内のif
内でlocation @404
の正規表現比較を行う代わりに、グローバルベースのmap
ディレクティブを使用することをお勧めします。
また、proxy_pass
と、それが含まれるlocation
の両方の末尾のスラッシュにも注意してください 関連する回答によると非常に重要です 。
参照:
そのスラッシュがnginxプロキシジェンキンに追加されると、「リバースプロキシの設定が壊れているようです」というエラーが表示されます。
proxy_pass http://localhost:8080/;
Remove this -----------------------------^
読むべき
proxy_pass http://localhost:8080;