Apache 2.4 轉換 .htaccess 並將其重寫為 vhost.conf
我正在重寫從舊開發團隊收到的 Apache 2.4 配置。
我有大約 200 行類似的配置,我無法理解我需要更改此程式碼以將其從虛擬主機移至虛擬主機的原理
.htaccess
。RewriteCond %{QUERY_STRING} ^$ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_URI} !(.*)/$ RewriteCond %{REQUEST_URI} !^/application-module/(.*)$ RewriteCond %{REQUEST_URI} !(.*)json$ [NC] RewriteCond %{REQUEST_URI} !playground/local-loader/(.*)$ [NC] RewriteRule ^(.*)$ /$1/ [R,L,NC]
當我將它移到虛擬主機時,我的網站在我不理解的地方崩潰了。
這取決於您在
<VirtualHost>
容器中放置這些指令的位置。如果您正在使用
<Directory>
容器(即目錄上下文)並完全禁用.htaccess
覆蓋(否則.htaccess
將覆蓋<Directory>
容器!)那麼您幾乎可以按原樣複製指令(假設<Directory>
容器引用與文件相同的目錄.htaccess
)。但是,如果您將這些指令直接放在
<VirtualHost>
容器內(容器外<Directory>
),即。在虛擬主機上下文中,您需要進行一些更改。這是因為指令在請求被映射到文件系統之前被更早地處理。在您發布的指令中,只需要進行兩項更改:
- 在虛擬主機上下文中,
REQUEST_FILENAME
伺服器變數尚未解析為文件名。它與REQUEST_URI
(即請求的 URL)相同。因此,您的文件系統檢查將始終失敗,條件將始終成功!您要麼需要使用前瞻。例如。%{LA-U:REQUEST_FILENAME}
,或自己構造絕對文件名。例如。%{DOCUMENT_ROOT}%{REQUEST_URI}
. 例如:RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
- 在虛擬主機上下文中,
RewriteRule
模式匹配的 URL 路徑是相對於根的(以斜杠開頭)。而.htaccess
其中是相對於包含.htaccess
文件的目錄 - 減去斜線前綴。因此,所寫的規則將導致 URL 路徑的開頭出現雙斜杠,它應該改寫如下:RewriteRule ^/(.*)$ /$1/ [R,L]
(
NC
這裡不需要標誌。)或者(最好)不要在這裡使用反向引用,
REQUEST_URI
而是使用伺服器變數(這自然也會起作用.htaccess
)。例如:RewriteRule ^ %{REQUEST_URI}/ [R,L]
(*旁白:*這可能也應該是 301 永久重定向(即。
R=301
)。就目前而言,這將預設為 302 臨時重定向。但只有更改為 301 - 如果這是意圖 - 一旦您確認它有效如預期。)因此,總而言之,這將變為:
RewriteCond %{QUERY_STRING} ^$ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f RewriteCond %{REQUEST_URI} !(.*)/$ RewriteCond %{REQUEST_URI} !^/application-module/(.*)$ RewriteCond %{REQUEST_URI} !(.*)json$ [NC] RewriteCond %{REQUEST_URI} !playground/local-loader/(.*)$ [NC] RewriteRule ^/(.*)$ /$1/ [R,L]
在旁邊:
通過將文件系統檢查(相對昂貴)移至最後一個條件並將檢查請求是否尚未以斜杠結束的條件移至指令,可以立即對上述內容進行一些優化
RewriteRule
。此外,不需要(.*)
每個*條件中的正則表達式子模式。*因此,上面可以更有效地重寫:RewriteCond %{QUERY_STRING} ^$ RewriteCond %{REQUEST_URI} !^/application-module/ RewriteCond %{REQUEST_URI} !json$ [NC] RewriteCond %{REQUEST_URI} !playground/local-loader/ [NC] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f RewriteRule !/$ %{REQUEST_URI}/ [R,L]
如果您排除包含(看起來像)文件副檔名的請求,則可以完全刪除文件系統檢查,但這可能取決於您的文件結構。
檢查的條件
!json$
看起來應該真的是檢查.json
文件副檔名,即。!\.json$
. (這與我上面關於排除所有具有“文件副檔名”的請求的評論有關。)檢查查詢字元串是否為空的第一個條件似乎有點奇怪(因為在 URL 路徑中附加斜杠時是否存在查詢字元串並不重要),但我認為這必須是特定的要求?