Nginx 将 url 重写为 index.php 参数
Nginx rewrite urls as index.php parameters
我最近从 apache 切换到 nginx。
我的应用程序位于 /var/www/html 下并具有以下结构:
# tree -a /var/www/html
/var/www/html
├── .htaccess
├── folder1
│ ├── .htaccess
│ └── index.php
├── folder2
│ ├── .htaccess
│ └── index.php
├── index.php
├── file1.php
└── file2.php
所有目录下的.htaccess文件都一样:
# cat /var/www/html/.htaccess
AddDefaultCharset UTF-8
Options +FollowSymLinks
Options -Indexes
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(assets)/ - [L,NE]
RewriteRule ^/?$ index.php?param1=main [QSA,L]
RewriteRule ^([-a-zA-Z0-9_]+)/$ index.php?param1= [QSA,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ index.php?param1=¶m2= [QSA,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ index.php?param1=¶m2=¶m3= [QSA,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ index.php?param1=¶m2=¶m3=¶m4= [QSA,L]
RewriteRule ^file1.xml$ file1.php [L]
RewriteRule ^file2.xml$ file2.php [L]
ErrorDocument 400 /error/400/
ErrorDocument 401 /error/401/
ErrorDocument 403 /error/403/
ErrorDocument 404 /error/404/
ErrorDocument 500 /error/500/
RedirectMatch (.*)\.inc /error/404/
RedirectMatch (.*)\.tpl /error/404/
现在我正在尝试构建 nginx 配置。我的目标是进行以下重写:
example.com or example.com/ -> example.com/index.php?param1=main
example.com/anything or example.com/anything/ -> example.com/index.php?param1=anything
example.com/anything/else or example.com/anything/else/ -> example.com/index.php?param1=anything¶m2=else
etc...
folder1 和 folder2 也一样
example.com/folder1 or example.com/folder1/ -> example.com/folder1/index.php?param1=main
example.com/folder1/anything or example.com/folder1/anything/ -> example.com/folder1/index.php?param1=anything
etc...
Nginx 配置目前看起来像:
server {
listen 443 ssl;
server_name example.com;
charset utf-8;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
root /var/www/html;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
我使用了在线转换器并在 location / {
下放置了规则,但这没有用。 Url 喜欢示例。com/anything 显示 404 和示例。com/anything/ 尝试下载文件
有不止一种方法可以做到这一点。但以下示例使用命名位置将所有重写规则收集在一起。
location / {
try_files $uri $uri/ @rewrite;
}
location @rewrite {
rewrite ^/$ /index.php?param1=main? last;
rewrite ^/([-a-zA-Z0-9_]+)/$ /index.php?param1=? last;
rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ /index.php?param1=¶m2=? last;
rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ /index.php?param1=¶m2=¶m3=? last;
rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ /index.php?param1=¶m2=¶m3=¶m4=? last;
rewrite ^/file1.xml$ /file1.php last;
rewrite ^/file2.xml$ /file2.php last;
return 404;
}
所有 Nginx URI 都以 /
开头。我假设默认操作是 return 404 如果 none 规则匹配。尾随 ?
可防止将任何原始参数附加到重写的 URI,如果要附加原始参数,请删除尾随 ?
。有关详细信息,请参阅 this document。
注意:在您的问题中,您声明要接受 example.com/anything/else
或 example.com/anything/else/
。这不是现有 .htaccess
所做的。要使结尾的 /
可选,请在 $
之前的最后一个 /
之后添加一个 ?
。例如:
rewrite ^/([-a-zA-Z0-9_]+)/?$ /index.php?param1=? last;
您可以对其他文件夹重复此模式,但看起来会很乱。此逻辑属于 index.php
,但下面给出了一个 Nginx 示例:
location /folder1 {
try_files $uri $uri/ @rewrite1;
}
location @rewrite1 {
rewrite ^/folder1/?$ /folder1/index.php?param1=main? last;
rewrite ^/folder1/([-a-zA-Z0-9_]+)/$ /folder1/index.php?param1=? last;
...
}
注意正则表达式和重写的URI都需要包含文件夹名称。
我最近从 apache 切换到 nginx。 我的应用程序位于 /var/www/html 下并具有以下结构:
# tree -a /var/www/html
/var/www/html
├── .htaccess
├── folder1
│ ├── .htaccess
│ └── index.php
├── folder2
│ ├── .htaccess
│ └── index.php
├── index.php
├── file1.php
└── file2.php
所有目录下的.htaccess文件都一样:
# cat /var/www/html/.htaccess
AddDefaultCharset UTF-8
Options +FollowSymLinks
Options -Indexes
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(assets)/ - [L,NE]
RewriteRule ^/?$ index.php?param1=main [QSA,L]
RewriteRule ^([-a-zA-Z0-9_]+)/$ index.php?param1= [QSA,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ index.php?param1=¶m2= [QSA,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ index.php?param1=¶m2=¶m3= [QSA,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ index.php?param1=¶m2=¶m3=¶m4= [QSA,L]
RewriteRule ^file1.xml$ file1.php [L]
RewriteRule ^file2.xml$ file2.php [L]
ErrorDocument 400 /error/400/
ErrorDocument 401 /error/401/
ErrorDocument 403 /error/403/
ErrorDocument 404 /error/404/
ErrorDocument 500 /error/500/
RedirectMatch (.*)\.inc /error/404/
RedirectMatch (.*)\.tpl /error/404/
现在我正在尝试构建 nginx 配置。我的目标是进行以下重写:
example.com or example.com/ -> example.com/index.php?param1=main
example.com/anything or example.com/anything/ -> example.com/index.php?param1=anything
example.com/anything/else or example.com/anything/else/ -> example.com/index.php?param1=anything¶m2=else
etc...
folder1 和 folder2 也一样
example.com/folder1 or example.com/folder1/ -> example.com/folder1/index.php?param1=main
example.com/folder1/anything or example.com/folder1/anything/ -> example.com/folder1/index.php?param1=anything
etc...
Nginx 配置目前看起来像:
server {
listen 443 ssl;
server_name example.com;
charset utf-8;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
root /var/www/html;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
我使用了在线转换器并在 location / {
下放置了规则,但这没有用。 Url 喜欢示例。com/anything 显示 404 和示例。com/anything/ 尝试下载文件
有不止一种方法可以做到这一点。但以下示例使用命名位置将所有重写规则收集在一起。
location / {
try_files $uri $uri/ @rewrite;
}
location @rewrite {
rewrite ^/$ /index.php?param1=main? last;
rewrite ^/([-a-zA-Z0-9_]+)/$ /index.php?param1=? last;
rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ /index.php?param1=¶m2=? last;
rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ /index.php?param1=¶m2=¶m3=? last;
rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ /index.php?param1=¶m2=¶m3=¶m4=? last;
rewrite ^/file1.xml$ /file1.php last;
rewrite ^/file2.xml$ /file2.php last;
return 404;
}
所有 Nginx URI 都以 /
开头。我假设默认操作是 return 404 如果 none 规则匹配。尾随 ?
可防止将任何原始参数附加到重写的 URI,如果要附加原始参数,请删除尾随 ?
。有关详细信息,请参阅 this document。
注意:在您的问题中,您声明要接受 example.com/anything/else
或 example.com/anything/else/
。这不是现有 .htaccess
所做的。要使结尾的 /
可选,请在 $
之前的最后一个 /
之后添加一个 ?
。例如:
rewrite ^/([-a-zA-Z0-9_]+)/?$ /index.php?param1=? last;
您可以对其他文件夹重复此模式,但看起来会很乱。此逻辑属于 index.php
,但下面给出了一个 Nginx 示例:
location /folder1 {
try_files $uri $uri/ @rewrite1;
}
location @rewrite1 {
rewrite ^/folder1/?$ /folder1/index.php?param1=main? last;
rewrite ^/folder1/([-a-zA-Z0-9_]+)/$ /folder1/index.php?param1=? last;
...
}
注意正则表达式和重写的URI都需要包含文件夹名称。