“ proxy_pass”不能在正则表达式指定的位置包含URI部分

W.K*_*K.S 4 nginx

我开发了一个URL缩短Web应用程序。

它由两个单独的Docker容器组成:一个包含后端REST api,另一个包含前端静态网站。

这两个容器链接到nginx容器。此nginx容器的配置如下:

worker_processes 1;

events { worker_connections 1024; }

http {
    upstream api {
        server short-url:8080;
    }

    upstream frontend {
        server short-url-frontend:8081;
    }

    gzip on;
    gzip_vary on;
    gzip_min_length 860;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types text/plain text/css text/xml application/javascript application/x-javascript application/xml;
    gzip_disable "MSIE [1-6]\.";

    server {
        listen 80;
        root    /user/share/nginx/html;

        location /urlshortener/v1 {
            proxy_pass         http://api/urlshortener/v1;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
        }

        location ~ ^/([A-Za-z0-9]+) {
            rewrite ^/([A-Za-z0-9]+) /$1
            proxy_pass         http://api/urlshortener/v1;
        }

        location / {
            proxy_pass          http://frontend;
            proxy_set_header    Host              $host;
            proxy_set_header    X-Real-IP         $remote_addr;
            proxy_set_header    X-Forwarded-for   $remote_addr;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

如果网址以结尾/urlshortening/v1,则代表后端。

如果网址以开头/,则代表代理到前端。

缩短的网址,例如/3xTy/a0q需要代理到后端,以便可以将用户导航到原始网址。为此,我使用正则表达式定义了一个位置。

location ~ ^/([A-Za-z0-9]+) {
    rewrite ^/([A-Za-z0-9]+) /$1
   proxy_pass         http://api/urlshortener/v1;
}
Run Code Online (Sandbox Code Playgroud)

此代码块给我以下错误:

2018/11/17 16:47:03 [emerg] 1#1:“ proxy_pass”不能在正则表达式指定的位置,命名位置内,“ if”语句内或“ limit_except”块内包含URI部分/etc/nginx/nginx.conf:36

我已经看了几个例子,并回顾了许多答案,我相信我的配置应该可以工作。有人可以解释为什么我遇到此错误吗?

Moj*_*ian 11

我遇到了同样的错误,正确的答案对我的情况没有帮助。这是我有问题的配置:

# proxying wordpress static files
location ~* (((product|blog|product-category)\/.*)|(\.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)))$ {
    proxy_pass https://mainhost.cdkeysell.ir/;
    ...
}
Run Code Online (Sandbox Code Playgroud)

/因此,在将其与具有类似配置但没有此类错误的其他网站进行比较后,我发现可以通过在配置末尾删除后者来简单地解决此问题proxy_pass

# proxying wordpress static files
location ~* (((product|blog|product-category)\/.*)|(\.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)))$ {
    # proxy_pass https://mainhost.cdkeysell.ir/; ==> final `/` caused error
    proxy_pass https://mainhost.cdkeysell.ir;
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢,删除最后的“/”解决了问题。 (2认同)

Ric*_*ith 7

如果将URI与正则表达式中proxy_pass语句一起使用, location需要使用一个或多个变量来构建整个URI。有关详细信息,请参见此文档

因此,替代方法是(1),从location表达式中捕获URI 并将其添加到proxy_pass语句中。例如:

location ~ ^/([A-Za-z0-9]+) {
    proxy_pass http://api/urlshortener/v1/$1;
}
Run Code Online (Sandbox Code Playgroud)

或(2),proxy_pass不使用URI部分,而使用构造所需的URI rewrite...break。例如:

location ~ ^/([A-Za-z0-9]+) {
    rewrite ^/([A-Za-z0-9]+) /urlshortener/v1/$1 break; 
    proxy_pass http://api;
}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参见此文档