簡體   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