Apache 2.4 轉換.htaccess並重寫為vhost.conf

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]

當我將其移動到虛擬主機時,我的網站在我不明白的地方崩潰了。

答案1

這取決於<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
    
  • 在一個虛擬主機context,匹配的 URL 路徑RewriteRule 圖案是相對根的(以斜線開頭)。而 in.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 路徑中附加斜線時是否有查詢字串並不重要),但我認為這一定是一個特定的要求?

相關內容