我很確定問題是%{REQUEST_FILENAME}沒有在 URI 更改時參考 URI,而是在請求時參考。
我有一些這樣的代碼:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule app/?(.*)$ /some-site/map-app/$1 [NC,QSA]
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule some-site/map-app/?(.*)$ /some-site/map-app/index.html [NC,L,QSA]
</IfModule>
效果應該是這樣
/app/some-site/map-app搜索檔案時轉到 ->- 如果失敗(通常會因為它是 SPA),則轉到
/some-site/map-app/index.html
出于某種原因,它正在重寫index.html回退的每條路徑。這意味著 #1 發生的次數足以滿足RewriteRule條件,但由于某種原因RewriteCond無法正常作業。
如果我洗掉 #2 的邏輯,檔案可以很好地解決,所以問題不在于它產生的路徑不好。
我已經閱讀了關于“RewriteCond Specials”的檔案(https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html)
為什么這兩個對于存在的路徑沒有失敗——并且已經由第一個邏輯塊生成——在第二個邏輯塊中?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
一些例子和期望的結果:
/app/->/some-site/map-app/index.html/app/map/id-3->/some-site/map-app/index.html/app/app.js->/some-site/map-app/app.js/app/assets/img/1.png->/some-site/assets/img/1.png(RewriteEngine 邏輯未包含在帖子中,但包含示例以防更改潛在答案)
uj5u.com熱心網友回復:
在第一次重寫之后,REQUEST_FILENAME服務器變數僅包含重寫的 URL 路徑(例如/some-site/map-app/foo),而不是重寫的 URL 將映射到的絕對檔案系統路徑。因此,REQUEST_FILENAME在此階段嘗試進行檔案系統檢查總是會失敗。
需要將請求重新映射回檔案系統,以便將REQUEST_FILENAME變數更新為絕對檔案系統路徑。這僅發生在重寫引擎開始時(以及每次通過之前)。
您可以通過在第一條規則中簡單地包含L( last) 標志來強制重寫引擎重新開始。這將結束當前輪次處理并將重寫的 URL 傳遞回重寫引擎,此時重寫的 URL 被重新映射到檔案系統并REQUEST_FILENAME進行更新。
或者,不要REQUEST_FILENAME在第二條規則中使用,而是從DOCUMENT_ROOT重寫的 URL 路徑手動構造絕對檔案名。
例如:
# If the previously rewritten URL does not map to a file (or directory)...
RewriteCond %{DOCUMENT_ROOT}/$0 !-f
RewriteCond %{DOCUMENT_ROOT}/$0 !-d
RewriteRule ^some-site/map-app(?:$|/(.*)) /some-site/map-app/index.html [NC,L]
哪里$0是RewriteRule 模式將匹配的整個 URL 路徑的反向參考。
您現有的正則運算式 ( RewriteRule pattern )存在問題。正則運算式app/?(.*)$匹配,appanything因為斜杠是可選的,我確定這不是本意。想必你想匹配apporapp/或app/<something>? 這也應該錨定到 URL 路徑的開頭,否則,它也會匹配/some-site/map-app/<something>(用于第二條規則)。這同樣適用于第二條規則(在上面更新)。
因此,請嘗試以下操作(如果未L在第一條規則中使用該標志):
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^app(?:$|/(.*)) /some-site/map-app/$1 [NC]
# If the previously rewritten URL does not map to a file (or directory)...
RewriteCond %{DOCUMENT_ROOT}/$0 !-f
RewriteCond %{DOCUMENT_ROOT}/$0 !-d
RewriteRule ^some-site/map-app(?:$|/(.*)) /some-site/map-app/index.html [NC,L]
不需要<IfModule>包裝器或重復RewriteEngine指令。該QSA(查詢字串追加)標志也是多余的,因為這是默認動作。我也會謹慎使用該NC標志(在內部重寫時),因為這允許/app和/APP映射到相同的 URL(輕微的重復內容問題)。
我也想知道目錄檢查是否真的有必要?
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/357886.html
