web-dev-qa-db-ja.com

バックエンド301/302リダイレクトをインターセプトし(proxy_pass)、別のロケーションブロックに書き換えることは可能ですか?

Nginxフロントエンドの後ろにいくつかのバックエンドがあります。

これらのバックエンドによって送信された301/302リダイレクトをインターセプトして、nginxにそれらを処理させることは可能ですか?

私たちは何かを単独で考えていました。

error_page 302 = @target;

しかし、301/302リダイレクトが404などと同じように処理できるとは思えません...つまり、error_pageはおそらく200などのエラーコードに適用されませんか?

要約すると:

私たちのバックエンドはたまに301/302を送り返します。 nginxにこれらをインターセプトさせ、それらを別のロケーションブロックに書き換えて、他のさまざまなことができるようにしたいと考えています。

可能?

ありがとう!

20
anonymous-one

proxy_redirectディレクティブ:

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect

Nginxは依然としてクライアントに301/302を返しますが、proxy_redirectLocationヘッダーを変更し、クライアントはLocationヘッダーで指定されたURLに新しいリクエストを行う必要があります。

このようなものは、nginxへの後続のリクエストを行う必要があります。

proxy_redirect http://upstream:port/ http://$http_Host/;

20
Tuomo Kestilä

リダイレクト先が任意の外部URLである場合のより一般的なケースを解決することに成功しました。

server {
    ...

    location / {
        proxy_pass http://backend;
        # You may need to uncomment the following line if your redirects are relative, e.g. /foo/bar
        #proxy_redirect / /;
        proxy_intercept_errors on;
        error_page 301 302 307 = @handle_redirects;
    }

    location @handle_redirects {
        set $saved_redirect_location '$upstream_http_location';
        proxy_pass $saved_redirect_location;
    }
}

あなたの説明に近い代替アプローチは、この質問に対するServerFaultの回答で説明されています。 https://serverfault.com/questions/641070/nginx-302-redirect-resolve-internally

6
Vlad Frolov

複数のリダイレクトに従う必要がある場合は、Vladのソリューションを次のように変更します。

1)追加

recursive_error_pages on;

location /

2)追加

  proxy_intercept_errors on;
  error_page 301 302 307 = @handle_redirect;

location @handle_redirects セクション。

4
drott

相対的な場所については、proxy_redirectの詳細をご覧ください

場合

location /api/ {
  proxy_pass http://${API_Host}:${API_PORT}/;
}
  • バックエンドは/api/接頭辞がない相対位置にリダイレクトします
  • ブラウザはリダイレクトに従い、理解の壁にぶつかる

解決

location /api/ {
  proxy_pass http://${API_Host}:${API_PORT}/;
  proxy_redirect ~^/(.*) http://$http_Host/api/$1;
}
2
Arnaud P