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

时间:2013-11-27 22:39:03

标签: redirect nginx http-status-code-301 reverse-proxy http-status-code-302

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

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

我们只是把事情弄清楚:

error_page 302 = @target;

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

总结一下:

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

可能的?

谢谢!

4 个答案:

答案 0 :(得分:19)

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

答案 1 :(得分:6)

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

答案 2 :(得分:3)

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

1)添加

recursive_error_pages on;

location /

2)添加

  proxy_intercept_errors on;
  error_page 301 302 307 = @handle_redirect;

location @handle_redirects部分。

答案 3 :(得分:0)

有关wire.iterancestors() wire.get('parent') wire.getroot() wire.find('..') 的更多信息,有关相对位置

案例

proxy_redirect
  • 后端重定向到一个相对位置,该位置缺少location /api/ { proxy_pass http://${API_HOST}:${API_PORT}/; } 前缀
  • 浏览器遵循重定向并造成一堵理解墙

解决方案

/api/