我正在尝试制定 Ngix 重写规则,但没有成功。
服务器中基本文件结构如下:
base url/
├─ index.php
├─ users.php
├─ login.php
├─ register.php
example.com/users.php?&user-id=john
应该重定向到example.com/john
上述重定向仅当。john
数据库中存在时才有效,如果不存在,则出现 404 错误- 导航到 example.com (基本网址)应该显示
index.php
register.php
并且login.php
页面应该可以工作
我尝试了以下方法:
重写 ^/(.*)$ /users.php?&user-id=$1 last; 并且
https://www.example.com/john
有效,但任何其他请求都会传递给users.php
(我无法导航到index.php
)try_files $uri $uri /users.php?&user-id=$uri;
.在这种情况下,导航到https://www.example.com/john
显示一个空users.php
文件。还可以导航到根目录中的其他文件,例如index.php
显示users.php
。
以下是完整的服务器块配置(域名已被替换):
server {
root /var/www/mydomain.com;
index index.html index.htm index.php;
server_name mydomain.com www.mydomain.com;
location / {
# try_files $uri $uri/ =404;
rewrite ^/(.*)$ /users.php?&user-id=$1 last;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.mydomain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name mydomain.com www.mydomain.com;
}
server {
if ($host = mydomain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name mydomain.com www.mydomain.com;
listen 80;
return 404; # managed by Certbot
}
答案1
我认为你需要location
像这样的一个区块:
location ~ /(.*)$ {
try_files $uri $uri/ /users.php?user-id=$1;
}
将捕获 URI变量(.*)
之后的部分。/
然后,try_files
首先检查指定的文件是否$uri
存在。如果不存在,则将请求传递给users.php
其中的user-id
参数设置为从中捕获的内容location
。
这意味着,URLhttps://example.com/john
将从 开始提供服务/users.php?user-id=john
。
在您的问题中,您使用了?&user-id
符号。这是不正确的。?
指定 URL 的查询参数部分的开始,&
是查询参数之间的分隔符。因此,?
就足够了。
另一个注意事项是,您可能希望在正则表达式中进行更精确的匹配,例如~ ^/([a-zA-Z0-9]+)$
。这仅匹配字母数字字符。