在Nginx中修改$ request_uri

Nar*_*asK 10 nginx

我在Nginx服务器上运行了多个应用程序:

http://example.com/app1/ctrl/view
http://example.com/app2/ctrl/view
...
Run Code Online (Sandbox Code Playgroud)

我想像这样分配这些应用程序DNS:

http://app1.example.com
http://app2.example.com
...
Run Code Online (Sandbox Code Playgroud)

为此,我尝试了以下服务器块:

server {
        listen 80;
        server_name app1.example.com;

        location / {
            proxy_pass http://example.com/app1/$request_uri;
        }
}
Run Code Online (Sandbox Code Playgroud)

如果用户未登录,我的应用程序将重定向到URI:

app1/ctrl/user/login?_next=/app/ctrl/view
Run Code Online (Sandbox Code Playgroud)

基本上$request_uri成为(注意加倍的app1实例):

app1/app1/ctrl/user/login?_next=/app/ctrl/view
Run Code Online (Sandbox Code Playgroud)

有没有一种方便的方法来修改$request_uri或更好的方法来解决这个问题?

EDIT1

看来我用以下服务器块解决了我的问题:

server {
        listen 80;
        server_name app1.example.com;

        location / {

            set $new_request_uri $request_uri;

            if ($request_uri ~ ^/app1/(.+)$) {
                set $new_request_uri $1;
            }

            proxy_pass http://example.com/app1/$new_request_uri;
        }
}
Run Code Online (Sandbox Code Playgroud)

如果有人知道更好(或正确" Nginx")的方式,请毫不犹豫地发布答案.

EDIT2

根据评论,我也尝试了以下内容:

server {
        listen 80;
        server_name app1.example.com;

        location / {
            proxy_pass http://example.com/app1/;
            proxy_redirect /app1/ /;
        }

        location ~ ^/app1/(.+)$ {
            return 301 http://$server_name/$1;
        }
}
Run Code Online (Sandbox Code Playgroud)

这个在屏幕上看起来更好,因为它完全消除了部件中的app1实例$request_uri,但是你必须有两个location块.

EDIT3

显然解决我问题的最有效方法是如下配置:

server {
        listen 80;
        server_name app1.example.com;

        location / {
            proxy_pass http://example.com/app1/;
            proxy_redirect /app1/ /;
        }

        location /app1/ {
            rewrite ^/app1(.+) $1 permanent;
        }
}
Run Code Online (Sandbox Code Playgroud)

这是因为Nginx总是尝试匹配最长的prefix第一个然后(如果^~修饰符不存在)开始顺序处理regexes直到regex match找到第一个.从本质上讲,这意味着所有regexes请求都会被处理,无论其中任何一个是否匹配,因此最好有regexes内部location指令.

Ale*_*Ten 7

你不需要走复杂的路。解决方案更简单

server {
        listen 80;
        server_name app1.example.com;

        location / {
            proxy_pass http://app1.example.com/app1/;
        }

        location /app1/ {
            proxy_pass http://app1.example.com/app1/;
            # or
            # rewrite ^/app1(.+) $1 permanent;
        }
}
Run Code Online (Sandbox Code Playgroud)

Nginx 将负责添加/app1/到请求并将其从标头中删除Location

请参阅proxy_redirect指令。