繁体   English   中英

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

[英]Convert Apache rewrite rules (front-controller) to Nginx

我需要一个小手来修复 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;
  }

我有一些在线转换器,但正在努力让它继续运行。

 <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]

这是一个相对标准的“前端控制器”模式。 但是,您传递给index.php脚本的url参数值不包含斜杠前缀。 实现这一点恰好需要在 Nginx 上执行一个额外的步骤。通常您只需传递 URL(包括斜杠前缀)并让您的脚本处理它。 (虽然你根本不需要传递 URL 路径,因为这可以从请求的 URL 路径中解析出来——尽管它允许你“覆盖”请求的 URL 路径。)

root指令之后,设置目录“index”文件:

index index.php;

当请求文档根时,这是必需的(与 Apache 相同)。

在最后一个location块之后,为“前端控制器”添加另一个块:

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

$1反向引用指的是location header 中捕获的子模式 - 这包含 URL 路径,减去斜杠前缀。

额外的$is_args$args是 append 初始请求中可能存在的任何其他查询字符串所必需的。 (这相当于 Apache 上的QSA mod_rewrite 标志。)

但是,如果您可以在url参数中包含脚本的 URL 路径上的斜杠前缀,那么上述内容可以“简化”为:

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

但请注意,此版本与等效的 Apache/ .htaccess指令并不完全相同。


或者,index.php之后将 URL 路径作为 PATH_INFO 传递


文件夹结构是这样的:

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

请注意,对于您的 Nginx 配置, public_html指令文档根目录,因此dev.example.com/直接引用此目录。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM