拦截后端301/302重定向(proxy_pass)并可能重写到另一个位置块?

问题描述 投票:0回答:4

我们的 nginx 前端后面有几个后端。

是否可以拦截这些后端发送的 301 / 302 重定向并让 nginx 处理它们?

我们正在做一些单独的事情:

error_page 302 = @target;

但我怀疑 301/302 重定向是否可以像 404 等一样处理......我的意思是,error_page 可能不适用于 200 等错误代码?

总结一下:

我们的后端偶尔会发回 301/302。我们希望 nginx 拦截这些,并将它们重写到另一个位置块,在那里我们可以用它们做许多其他事情。

可能吗?

谢谢!

redirect nginx http-status-code-301 reverse-proxy http-status-code-302
4个回答
28
投票

您可以使用

proxy_redirect
指令:

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

Nginx 仍将向客户端返回 301/302,但

proxy_redirect
将修改
Location
标头,客户端应向
Location
标头中给出的 URL 发出新请求。

这样的事情应该会让后续请求返回到 nginx:

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


14
投票

当重定向位置可以是任何外部 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


11
投票

如果需要遵循多个重定向,请修改Vlad的解决方案如下:

  1. 添加

    recursive_error_pages on;
    

    location /

  2. 添加

       proxy_intercept_errors on;
       error_page 301 302 307 = @handle_redirects;
    

    前往

    location @handle_redirects
    部分。


7
投票

有关

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.