【问题标题】:Nginx rewrite urls as index.php parametersNginx 将 url 重写为 index.php 参数
【发布时间】:2021-05-08 12:30:17
【问题描述】:

我最近从 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/ 尝试下载文件

【问题讨论】:

  • 请添加您使用的 nginx 配置文件,并更具体地描述“不起作用”的实际含义。
  • @arkascha 上传

标签: regex .htaccess nginx url-rewriting


【解决方案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,如果要附加原始参数,请删除尾随 ?。详情请见this document

注意:在您的问题中,您声明您希望接受example.com/anything/elseexample.com/anything/else/。这不是现有的.htaccess 所做的。要使尾随 / 可选,请在 $ 之前的最后 / 之后添加 ?。例如:

rewrite ^/([-a-zA-Z0-9_]+)/?$ /index.php?param1=$1? 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=$1? last;
    ...
}

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

【讨论】:

  • 谢谢,这对根文件夹非常有效。我尝试为 folder1 和 folder2 添加相同的方式,例如 location /folder1 { try_files $uri $uri/ @rewrite; } location @rewrite_folder1 { rewrite ^/$ /index.php?param1=main? last; rewrite ^/([-a-zA-Z0-9_]+)/$ /index.php?param1=$1? last; ... return 404; } 但对于 example.com/folder1/anything 之类的请求,它会返回 500 错误
  • 如果您想扩展您的问题,请使用 编辑 按钮。但是您还没有显示来自folder1.htaccess 文件的内容。
  • 谢谢。所有目录下的.htaccess文件都一样
  • 添加了更多描述。通常我有 3 个位置:/、/folder1 和 /folder2 对于所有位置,重写都是相等的,差异仅在 url:example.com、example.com/folder1 和 example.com/folder2
猜你喜欢
  • 2022-08-19
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-25
  • 2018-10-29
  • 1970-01-01
  • 2018-08-27
相关资源
最近更新 更多