Mod-Rewrite

如何使用 apache2 mod_rewrite 從文件根目錄重定向到文件夾

  • February 7, 2020

我在 Ubuntu 上有 Apache2 服務於多個主機。一些主機具有網站和 API 部分以及一些文件夾uploads,例如應該保留在文件根目錄之外。我想將它們組織在以下文件結構中:

domain
   uploads
   htdocs  //document root
       api
       site

問題是:

  1. 如何在不更改瀏覽器uri的情況下將除api文件根目錄之外的所有請求重定向到文件夾site
  2. 並將瀏覽器 uri 重寫為文件根目錄,以便直接向文件夾發出請求site,即,而不是在瀏覽器 uri中/site/..顯示/..

我嘗試了以下方法,但它會導致ERR_TOO_MANY_REDIRECTS

RewriteCond %{REQUEST_URI} !^/api/.*$
RewriteCond %{REQUEST_URI} !^/site.*
RewriteRule ^(.*)$ /site/$1 [L]

RewriteCond %{REQUEST_URI} ^/site/?(.*)
RewriteRule .* /%1 [R]

您將獲得一個重定向循環,因為重寫的 URL 與您要重定向的 URL 匹配。儘管存在標誌,但在.htaccess第一次重寫後重寫引擎會重新啟動。LL標誌只是停止目前傳遞,它不會停止所有處理。

  1. 如何在不更改瀏覽器uri的情況下將除api文件根目錄之外的所有請求重定向到文件夾site
  2. 並將瀏覽器 uri 重寫為文件根目錄,以便直接向站點文件夾發出請求,即,而不是在瀏覽器 uri中/site/..顯示/..

你把術語顛倒了。#1 實際上是“重寫”,而不是“重定向”。您正在內部重寫(URL 重寫)請求 - 可見 URL 沒有改變。#2是外部“重定向”,而不是“重寫”。與 3xx 外部重定向一樣 - 正在重定向瀏覽器。

我也會顛倒順序,所以你首先做#2 - 外部重定向。通常,重定向應始終在重寫之前進行。

請嘗試以下操作:

# Redirect direct requests for "/site/<anything>" to "/<anything>"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^site/(.*) /$1 [R=302,L]

# Rewrite "/<anything>" to "/site/<anything>"
# except for "/api" and "/site" itself.
RewriteRule !^(api|site)/ /site%{REQUEST_URI} [L]

RewriteCond檢查環境變數的重定向指令可防止REDIRECT_STATUS重定向循環。此變數在初始請求時為空,並在第一次成功重寫後設置為“200”(如 200 OK 狀態)。

第二條規則(重寫)使用否定模式來排除對/api/site目錄的請求。這避免了對單獨條件的需要。然後,我們需要在替換字元串中使用REQUEST_URI伺服器變數,而不是反向引用。

引用自:https://serverfault.com/questions/1002216