.htaccess 将Apache重写规则(前端控制器)转换为Nginx

yb3bgrhw  于 2023-01-17  发布在  Apache
关注(0)|答案(1)|浏览(180)

我需要一个小手修复Nginx重写规则。
文件夹结构是这样的:

  • dev.example.com/public_html〈〈包含站点

/public_html之外,我们有应用程序和数据文件夹
下面的.htaccess我需要转换如下

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteRule ^$ public_html/ [L]
  RewriteRule (.*) public_html/$1 [L]
</IfModule>
<IfModule mod_rewrite.c>
      Options -Multiviews
      RewriteEngine On
      RewriteBase /
      RewriteRule ^$ public_html/ [L]
      RewriteRule (.*) public_html/$1 [L]
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteRule  ^(.+)$ index.php?url=$1 [QSA,L]
    </IfModule>

我的Nginx配置有点像这样...

root /data/wwwroot/domain.com/public_html;
  
  include /usr/local/nginx/conf/rewrite/others.conf;
  #error_page 404 /404.html;
  #error_page 502 /502.html;
  
  location ~ [^/]\.php(/|$) {
    #fastcgi_pass remote_php_ip:9000;
    fastcgi_pass unix:/dev/shm/php-cgi.sock;
    fastcgi_index index.php;
    include fastcgi.conf;
  }

  location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ {
    expires 30d;
    access_log off;
  }
  location ~ .*\.(js|css)?$ {
    expires 7d;
    access_log off;
  }
  location ~ /(\.user\.ini|\.ht|\.git|\.svn|\.project|LICENSE|README\.md) {
    deny all;
  }
  location /.well-known {
    allow all;
  }

我有一些在线转换器,但努力让它去。

qacovj5a

qacovj5a1#

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteRule ^$ public_html/ [L]
  RewriteRule (.*) public_html/$1 [L]
</IfModule>

第一个.htaccess文件(public_html目录之上)在Nginx服务器上是不需要的,因为您已经将root配置为直接指向public_html目录。

<IfModule mod_rewrite.c>
  Options -Multiviews
  RewriteEngine On
  RewriteBase /
  RewriteRule ^$ public_html/ [L]
  RewriteRule (.*) public_html/$1 [L]
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule  ^(.+)$ index.php?url=$1 [QSA,L]
</IfModule>

并且此.htaccess文件(在/public_html目录中)没有意义。具体来说,前两个RewriteRule指令(重复父.htaccess文件中的指令)有错误,应该删除。如果处理,则会导致重写循环(500内部服务器错误)。
Options -MultiViews不适用于Nginx,因此可以忽略此规则。
因此,需要"转换"的相关指令如下:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule  ^(.+)$ index.php?url=$1 [QSA,L]

这是一个相对标准的"front-controller"模式。但是,您传递给index.php脚本的url参数值不包括斜杠前缀。实现这个 * exactly * 需要在Nginx上执行额外的步骤。通常,您只需传递包含斜杠前缀的URL,然后让脚本处理它。(尽管你根本不需要传递URL路径,因为它可以从请求的URL路径解析出来--尽管它允许你"覆盖"请求的URL路径。
root指令之后,设置目录"index"文档:

index index.php;

这在请求文档根目录时是必需的(与Apache相同)。
在最后一个location块之后,为"front-controller"添加另一个块:

location ~ ^/(.+) {
    try_files $uri $uri/ /index.php?url=$1$is_args$args;
}

$1反向引用引用location头中捕获的子模式--它包含URL路径,减去斜杠前缀。
附加的$is_args$args是附加初始请求中可能存在的任何附加查询字符串所必需的(这相当于Apache上的QSA mod_rewrite标志)。
但是,如果您同意在url参数中包含脚本URL路径上的斜杠前缀,则上述内容可以"简化"为:

location / {
    try_files $uri $uri/ /index.php?url=$uri$is_args$args;
}

但请注意,此版本与等效的Apache/.htaccess指令并不完全相同。
另一种选择,passing the URL-path as PATH_INFO after index.php
文件夹结构是这样的:

  • dev.example.com/public_html〈〈包含站点

注意,在Nginx配置中,public_html指令 * 是 * 文档根目录,因此dev.example.com/直接引用此目录。

相关问题