Nginx 位置正则表达式不适用于代理传递

Nie*_*els 53 nginx proxy regex proxypass

我正在尝试让这 2 个位置指令在 Nginx 中工作,但是在启动 Nginx 时出现了一些错误。

   location ~ ^/smx/(test|production) {
        proxy_pass   http://localhost:8181/cxf;
    }

    location ~ ^/es/(test|production) {
        proxy_pass   http://localhost:9200/;
    }
Run Code Online (Sandbox Code Playgroud)

这是我收到的错误:

nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block
Run Code Online (Sandbox Code Playgroud)

有没有人觉得很熟悉?我在这里错过了什么?

mar*_*ark 64

Xaviar的精彩回答的一个小补充:

如果您碰巧不太熟悉 nginx,那么在proxy_pass指令末尾添加斜杠有一个重要区别。

以下不起作用

location ~* ^/dir/ {
  rewrite ^/dir/(.*) /$1 break;
  proxy_pass http://backend/;
Run Code Online (Sandbox Code Playgroud)

但这个确实:

location ~* ^/dir/ {
  rewrite ^/dir/(.*) /$1 break;
  proxy_pass http://backend;
Run Code Online (Sandbox Code Playgroud)

不同之/处在于proxy_pass指令末尾的。

  • 后面的`/` 修复了我的配置问题,很难捕捉,谢谢! (4认同)

Xav*_*cas 30

它告诉您不能在正则表达式位置使用代理传递指令中的 URI。这是因为 nginx 无法将与location块中正则表达式匹配的 URI 部分替换为在proxy_pass指令中以通用方式传递的部分。

简单地想象一下您的位置正则表达式是/foo/(.*)/bar,并且您指定proxy_pass http://server/testnginx 必须将您的位置正则表达式映射到上层的另一个正则表达式,因为您不想以/foo/test/bar/something但结尾/test/something。所以这在本地是不可能的。

所以对于这部分使用以下应该工作:

server {

   [ ... ]

    location ~ ^/smx/(test|production) {
        rewrite ^/smx/(?:test|production)/(.*)$ /cxf/$1 break;
        proxy_pass http://localhost:8181;
    }

    location ~ ^/es/(test|production) {
        rewrite ^/es/(?:test|production)/(.*)$ /$1 break;
        proxy_pass http://localhost:9200;
    }

}
Run Code Online (Sandbox Code Playgroud)

但是,无法重写重定向以匹配位置块 URI 模式,因为它会重写正在处理的当前 URI,因此无法在重写之前Location根据初始请求更改标头。

  • 将路径移动到重写规则对我有用。谢谢。 (2认同)