Возможно перехват backend 301/302 перенаправления (proxy_pass) и переписывание на другой блок местоположения?

У нас есть пара backend, сидящих за нашими передними концами nginx.

Можно ли перехватывать 301/302 переадресации, отправленные этими бэкэндами и обрабатывать nginx?

Мы что-то делали только в строках:

error_page 302 = @target;

Но я сомневаюсь, что перенаправление 301/302 можно обрабатывать так же, как 404 и т.д. и т.д. Я имею в виду, что error_page, вероятно, не применяется к кодам ошибок 200 и т.д.

Итак, суммируем:

Наши серверы возвращают 301/302s время от времени. Мы хотели бы, чтобы nginx перехватил их и переписал их в другой блок местоположения, где мы могли бы делать с ними любое количество других вещей.

Возможные?

Спасибо!

Ответ 1

Вы можете использовать директиву proxy_redirect:

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

Nginx все равно вернет 301/302 клиенту, но proxy_redirect изменит заголовок Location, и клиент должен сделать новый запрос к URL-адресу, указанному в заголовке Location.

Что-то вроде этого должно сделать последующий запрос обратно на nginx:

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

Ответ 2

Мне удалось решить более общий случай, когда местом перенаправления может быть любой внешний 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

Ответ 3

Если вам нужно выполнить несколько переадресаций, измените решение Vlad следующим образом:

1) Добавить

recursive_error_pages on;

до location /.

2) Добавить

  proxy_intercept_errors on;
  error_page 301 302 307 = @handle_redirect;

в раздел location @handle_redirects.