Nginx 重写的一些问题 - 将请求从文件夹转发到子域,然后进一步处理

Nginx 重写的一些问题 - 将请求从文件夹转发到子域,然后进一步处理

我正在尝试执行以下操作,但也许我只是陷入了一个愚蠢的语法错误。

旧站点有一个名为数据库的子站点,因此我们有: www.example.com(被彻底取代)

www.example.com/database/< 很多东西 >

新的数据库地点:

database.example.com/ < 与之前不同的内容 >

在 example.com 的 nginx.conf 中:

location ^~/database {
        rewrite ^/database/?(.*)$ https://database.example.com/$1 permanent;
        }

这部分正在工作。

卷曲: curl -L -vwww.example.com/database/thisisatest

* Connected to www.example.com (<>) port 80 (#0)
> GET /database/thisisatest HTTP/1.1
[...]
< HTTP/1.1 301 Moved Permanently
[...]
< Location: https://database.example.com/thisisatest
<
* Ignoring the response-body
* Connection #0 to host www.example.com left intact
* Issue another request to this URL: 'https://database.example.com/thisisatest'

到目前为止一切顺利。现在我无法完成的部分是:

完整原始请求:

唯一区别:id= 的有效输入是 6 位数字,input= 是 textinput

目标:

  • 虚拟:database.example.com/search/XXXX
  • 真实:database.example.com/index.php?db=search&name=XXXX

第一个请求 id= 只能是 6 位数字才能构成有效请求。input= 可以是任何文本(德语/英语/西班牙语/法语/波兰语/中文和 0-9)

在 database.example.com 配置中:

从位置内 /

rewrite ^/search.php?input=(.+)/?$ index.php?db=search&name=$1 last;
rewrite ^/view.php?id=([0-9]+)$  index.php?db=search&name=$1 last;
rewrite ^/search/(.+)/?$ index.php?db=search&name=$1 last;

所以,这暂时还不起作用。我的逻辑有些不对。

database.example.com 的完整 nginx.conf:

server {
    listen 80;
    listen [::]:80;
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name database.example.com;

    ssl_certificate /etc/acme.sh/database.example.com/fullchain.pem;
    ssl_certificate_key /etc/acme.sh/database.example.com/privkey.pem;
    add_header Strict-Transport-Security max-age=15768000;



    root /var/webs/database.example.com/htdocs;
    
    access_log /var/webs/database.example.com/logs/access.log main;
    error_log /var/webs/database.example.com/logs/error.log warn;
    
    # Add index.php to the list if you are using PHP
    index index.php index.html index.htm;

    # serve static files directly
    location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)$ {
        access_log        off;
        expires           365d;
    }

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
     try_files $uri $uri/ =404;
     
########################################
##### THIS PART HERE DOES NOT WORK #####
########################################
     rewrite ^/search.php?input=(.+)/?$ index.php?db=search&name=$1 last;
     rewrite ^/view.php?id=([0-9]+)$  index.php?db=search&name=$1 last;
     rewrite ^/search/(.+)/?$ index.php?db=search&name=$1 last;
########################################
########################################     

     }

    
    # pass PHP scripts to FastCGI server
    #
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        include fastcgi_params;

        # With php-fpm (or other unix sockets):
         fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
       
    }

    location ~ /\.ht {
        deny all;
    }

     location ~ /\.git {
        deny all;
    }
}

显然,view.php 和 search.php 都不再作为真实文件存在 - 我只是向它们提出了需要修改的请求。

那么,我的逻辑哪里错了? :/ 任何帮助都值得感激。

答案1

location ~ \.php$块处理以 结尾的任何 URI .php,因此前两个rewrite语句永远不会被触发,因为它们在错误的location块中。

所有 Nginx URI 都以 开头/,因此重写的 URI 应该是/index.php为了正确操作。

rewrite和语句location与不包含查询字符串(从?开始的任何内容)的规范化 URI 进行匹配。查询字符串参数可用作名称以 开头的变量$arg_

location一种可能的解决方案是使用=and运算符将三个重写语句放入单独的块中^~。请参阅这个文件了解详情。

例如:

location / {
    try_files $uri $uri/ =404;
}

location = /search.php { 
    rewrite ^ /index.php?db=search&name=$arg_input? last;
}

location = /view.php { 
    rewrite ^ /index.php?db=search&name=$arg_id? last;
}

location ^~ /search/ {
    rewrite ^/search/(.+)/?$ /index.php?db=search&name=$1? last;
}

location ~ \.php$ { ... }

请注意,重写的 URI 带有尾部,?以防止附加原始查询字符串。请参阅这个文件了解详情。


另一种解决方案使用您原始的正则表达式,但需要针对$request_uri包含完整原始请求的变量执行。

例如:

map $request_uri $rewrite {
    default 0;
    ~^/search\.php\?input=(?<name>.+)/?$ /index.php?db=search&name=$name;
    ~^/view\.php\?id=(?<name>[0-9]+)$    /index.php?db=search&name=$name;
    ~^/search/(?<name>.+)/?$             /index.php?db=search&name=$name;
}

server {
    ...
    if ($rewrite) {
        rewrite ^ $rewrite? last;
    }
    ...
}

这个文件了解详情。

相关内容