Nginx 反向代理 + URL 重写

Nginx 反向代理 + URL 重写

Nginx 在端口 80 上运行,我使用它来反向代理 URL,路径/foo到端口是3200这样的:

location /foo {
                proxy_pass http://localhost:3200;
                proxy_redirect     off;
                proxy_set_header   Host $host;
}

这工作正常,但我在端口 上有一个应用程序3200,我不希望/foo将初始值发送到该应用程序。也就是说 - 当我访问 时http://localhost/foo/bar,我只希望/bar是应用程序收到的路径。所以我尝试将这一行添加到上面的位置块:

rewrite ^(.*)foo(.*)$ http://localhost:3200/$2 permanent;

这会导致 302 重定向(URL 发生变化),但我想要 301。我该怎么办?

答案1

从远程系统(例如客户端的 Web 浏览器)重定向到本地主机没有任何意义。因此重写标志永久(301)或重定向(302)在您的情况下不可用。

请尝试使用透明重写规则进行以下设置:

location  /foo {
  rewrite /foo/(.*) /$1  break;
  proxy_pass         http://localhost:3200;
  proxy_redirect     off;
  proxy_set_header   Host $host;
}

用于curl -i测试您的重写。规则的一个非常细微的改变都可能导致 nginx 执行重定向。

答案2

只要您在 proxy_pass 指令中指定 URI,简单的位置前缀匹配就可以实现这一点,而无需使用重写规则:

location /foo {
  proxy_pass http://localhost:3200/;
}

/注意指令末尾的附加内容proxy_pass。NGINX 将删除匹配的前缀/foo,并将剩余部分传递给 URI 处的后端服务器/。因此,http://myserver:80/foo/bar将发布到 处的后端http://localhost:3200/bar

来自NGINX 文档关于 proxy_pass

如果 proxy_pass 指令指定了 URI,那么当请求传递到服务器时,规范化请求 URI 中与位置匹配的部分将被指令中指定的 URI 替换:

答案3

最正确的方法和最佳做法通常如下:

location /foo/ {
    proxy_pass http://localhost:3200/; # note the trailing slash!
}

  • 注意尾部斜线proxy_pass,它会自动改变$uri变量,使/foo/前端与/后端相对应。无需显式rewrite指令。

  • 此外,请注意落后/location也非常重要——如果没有它,你的网站上的 URL 可能会看起来很奇怪(例如,除了/fooen之外还有/foo/en)。

    此外, with/中的尾部还确保了一些locationproxy_pass特殊处理按照该location指令的文件,有效地导致隐式location = /foo {return 301 /foo/;}

    因此,通过location像上面那样定义带有尾部斜杠的 ,您不仅可以确保没有斜杠后缀的 URL(如 )/fooen无效,而且还可以确保/foo没有尾部斜杠的 也将继续工作。


参考文档:

答案4

@Terabuck 抱歉,尚未回复。

您不应该使用 localhost,因为您依赖于应用程序在具有 hosts 文件的服务器上运行的事实。本地主机只是默认转换为 127.0.0.1。没有任何规定说您必须拥有此 hosts 文件。拥有一个 hosts 文件是很常见的。

拥有环回接口是另一个常见的依赖项,但您仍然依赖于网络堆栈上的环回接口。没有这两个接口的情况很少见。如果您担心这一点。至少在 unix/linux 上,您可以选择套接字。这将消除网络堆栈到达本地主机的需要。请谨慎使用此方法,因为主机操作系统上会出现一些因素。例如打开的文件数等。

相关内容