linux - 将 Apache 重写规则(前端 Controller )转换为 Nginx

标签 linux .htaccess nginx mod-rewrite url-rewriting

我需要一个小手来修复 Nginx 的重写规则。

文件夹结构如下:

  • dev.example.com/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>

我的 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>

您的 Nginx 服务器上不需要第一个 .htaccess 文件(位于 public_html 目录之上),因为您已经将 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]

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

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

index index.php;

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

在最后一个 location block 之后,为“前端 Controller ”添加另一个 block :

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

$1 反向引用指的是 location header 中捕获的子模式 - 它包含 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 .


Folder structure is like this:

  • dev.example.com/public_html << contain the site

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

关于linux - 将 Apache 重写规则(前端 Controller )转换为 Nginx,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75129102/

相关文章:

http - nginx 日志 http 状态 什么是 404 187

c++ - 在 C++ linux 中使用 popen 时的 stderr 输出

php - 使用 mod_rewrite 删除 .php 扩展并同时清理 GET url

c++ - GCC 和 MinGW (C++) 之间奇怪的输出差异

php - 我想使用重写规则来清除我的网址

php - .htaccess 内部服务器错误 : ErrorDocument not working (RewriteEngine on)

node.js - Nginx - 源服务器响应代码为 401 时的速率限制

elasticsearch - 无法连接到我的代理 elasticsearch 节点

linux - 如何在 c shell 中编写脚本,以便执行 `cd` 也会自动触发 `ll` 或 `ls`

linux - bash 解析服务名称