【问题标题】:Intercepting backend 301/302 redirects (proxy_pass) and rewriting to another location block possible?拦截后端 301/302 重定向(proxy_pass)并重写到另一个位置块可能吗?
【发布时间】:2013-12-13 19:15:33
【问题描述】:

我们的 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


    【解决方案1】:

    更多关于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;
    }
    

    【讨论】:

    • 在代理重定向中使用 $scheme:// 而不是 http:// 以使其在 https 上工作。
    【解决方案2】:

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

    1) 添加

    recursive_error_pages on;
    

    location /

    2) 添加

      proxy_intercept_errors on;
      error_page 301 302 307 = @handle_redirect;
    

    location @handle_redirects 部分。

    【讨论】:

      【解决方案3】:

      您可以使用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/;

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2012-11-20
          • 2017-04-20
          • 2010-09-28
          • 2016-06-21
          • 1970-01-01
          • 2019-04-12
          • 2014-01-09
          • 1970-01-01
          相关资源
          最近更新 更多