0

我最近从 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=$1 [QSA,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ index.php?param1=$1&param2=$2 [QSA,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ index.php?param1=$1&param2=$2&param3=$3 [QSA,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ index.php?param1=$1&param2=$2&param3=$3&param4=$4 [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&param2=else
etc...

文件夹 1 和文件夹 2 也是如此

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 / {但这不起作用。像 example.com/anything 这样的网址显示 404 和 example.com/anything/ 尝试下载文件

4

1 回答 1

1

有不止一种方法可以做到这一点。但以下示例使用命名位置来收集所有重写规则。

location / {
    try_files $uri $uri/ @rewrite;
}
location @rewrite {
    rewrite ^/$ /index.php?param1=main? last;
    rewrite ^/([-a-zA-Z0-9_]+)/$ /index.php?param1=$1? last;
    rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ /index.php?param1=$1&param2=$2? last;
    rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ /index.php?param1=$1&param2=$2&param3=$3? last;
    rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ /index.php?param1=$1&param2=$2&param3=$3&param4=$4? last;

    rewrite ^/file1.xml$ /file1.php last;
    rewrite ^/file2.xml$ /file2.php last;
    return 404;
}

所有 Nginx URI 都以前导/. 我假设如果没有任何规则匹配,默认操作是返回 404。尾随?可防止将任何原始参数附加到重写的 URI,如果要附加原始参数,请删除尾随?. 有关详细信息,请参阅此文档

注意:在您的问题中,您声明要接受example.com/anything/elseexample.com/anything/else/。这不是现有的.htaccess。要使尾随可选/,请在. 例如:?/$

rewrite ^/([-a-zA-Z0-9_]+)/?$ /index.php?param1=$1? last;

您可以对其他文件夹重复此模式,但它看起来会很乱。这个逻辑属于 inside 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=$1? last;
    ...
}

请注意,正则表达式和重写的 URI 都需要包含文件夹名称。

于 2021-02-04T09:20:56.377 回答