Mod-Rewrite

沒有 R 標誌的根的 RewriteRule 不起作用

  • August 8, 2015

我正在嘗試用文件做一個記憶體系統。而且我正在考慮使用 mod rewrite 來提供記憶體文件(如果存在),或者 php 文件(將創建 html 靜態記憶體)如果不存在。

這是我想出的第一個樣本

        <IfModule mod_rewrite.c>
           RewriteEngine On

           RewriteRule ^$ /cache/home.html [L,NC]
           RewriteCond %{REQUEST_URI} /cache/
           RewriteCond %{REQUEST_FILENAME} !-f
           RewriteRule ^cache/home.html /index.php [L]

           RewriteRule ^page/([0-9]*) /cache/page_$1.html [L,NC]
           RewriteCond %{REQUEST_URI} /cache/
           RewriteCond %{REQUEST_FILENAME} !-f
           RewriteRule ^cache/page_([0-9]*).html /page.php?&id=$1 [L]
       </IfModule>

這適用於內部頁面。如果我呼叫http://www.example.site/page/1>或<http://www.example.site/page/2它會根據文件是否存在正確地提供記憶體文件或 php 頁面。

問題是它不適用於主站點http://www.example.site

如果我為首頁添加重定向標誌,它實際上可以正常工作

RewriteRule ^$ /cache/home.html [L,NC,R]

但是,顯然,在這種情況下,如果我呼叫主站點並且我得到一個 http://www.example.site/cache/home.html,這不是我想要的。

以下是可能出現問題的幾行日誌:

[Wed Aug 05 11:59:11.751277 2015] [rewrite:trace1] [pid 30670] mod_rewrite.c(468): [client 10.1.1.1:53595] 10.1.1.1 - - [m.site.com/sid#7f7850ecb038][rid#7f7850e480a0/initial] [perdir /home/www/site.com/public/mobile/] internal redirect with /cache/home.html [INTERNAL REDIRECT]
[Wed Aug 05 11:59:11.751339 2015] [rewrite:trace3] [pid 30670] mod_rewrite.c(468): [client 10.1.1.1:53595] 10.1.1.1 - - [m.site.com/sid#7f7850ecb038][rid#7f7850e420a0/subreq] [perdir /home/www/site.com/public/mobile/] strip per-dir prefix: /home/www/site.com/public/mobile/index.html -&gt; index.html

雖然帶有 R 標誌

[Wed Aug 05 12:04:34.333591 2015] [rewrite:trace1] [pid 31746] mod_rewrite.c(468): [client 10.1.1.1:53613] 10.1.1.1 - - [m.site.com/sid#7f7850ec1038][rid#7f7850e440a0/initial] [perdir /home/www/site.com/public/mobile/] redirect to http://m.cmstest.site.com/cache/home.html [REDIRECT/302]
[Wed Aug 05 12:04:34.343609 2015] [rewrite:trace3] [pid 31746] mod_rewrite.c(468): [client 10.1.1.1:53613] 10.1.1.1 - - [m.site.com/sid#7f7850ec1038][rid#7f7850e420a0/initial] [perdir /home/www/site.com/public/mobile/] strip per-dir prefix: /home/www/site.com/public/mobile/cache/home.html -&gt; cache/home.html

似乎第一個沒有 R 標誌,在對 cache/home.html 進行正確的內部重定向之後,它會去尋找 index.html (實際上並不存在)

問題似乎出在子請求上,就像在這個答案中一樣:https ://stackoverflow.com/questions/9618865/mod-rewrite-mysterious-subreq

從日誌中可以看出,在第一次正確的內部重定向之後,第二次呼叫是對嘗試在根目錄中查找 index.html 的子請求。

我試圖-MultiViews在我連結的答案中添加選項,但這仍然不起作用。Apache 仍在關注網站根目錄中的子請求。

所以我最終得到了一個小的“hack”解決方案,它將檢查請求是否是子請求,在這種情況下,如果它正在尋找index.*根目錄中的文件,它將重定向到/cache/home.html

       RewriteCond %{IS_SUBREQ} t
       RewriteCond %{REQUEST_URI} ^(/index.\w+|/)?$
       RewriteRule ^ /cache/home.html [L]

從某種意義上說,這很好用,最終會做我想做的事情。

我會讓這個問題再開放一段時間,因為這仍然感覺像是一個“黑客”解決方案。不知道是否有更好的方法可以直接阻止這些子請求。

你的第一條規則說:

RewriteRule ^$ /cache/home.html [L,NC]

L標誌告訴 mod_rewrite 在該點停止處理,這是您要問的問題。“R”解決方法意味著新規則在第二次請求時按預​​期重寫,但在L第一次請求時會阻止它。此外,NC這裡的標誌是多餘的,因為路徑字元不會受到區分大小寫的影響。

雖然不是您問題的一部分,但也請重新考慮以下內容。

RewriteRule ^cache/home.html /index.php [L]

您可能想匹配^cache/page.html$,使其不接受cache/home.htmlxyz,實際影響可能很小。還有規則:

RewriteRule ^page/([0-9]*) /cache/page_$1.html [L,NC]

這些標誌可能和以前一樣不合適。該NC標誌實際上在這裡做了一些事情,但我認為這是不可取的。還要考慮你的正則表達式中的數字序列可以是零長度,我懷疑這是不可取的,所以也許你想要([0-9]+)?您可能還想用“$”終止它,因為目前您將匹配 eg /page/foobar,並且您也不想匹配/page/123foobar。所以你會有:

RewriteRule ^page/([0-9]+)$ /cache/page_$1.html

編輯:

請參閱下面的評論,了解為什麼匹配^$可能不適合您。此外,如果修復不起作用,請嘗試添加mod_rewrite:trace3到您的LogLevel 指令中,並準確找出問題所在。輸出很冗長,但您會學到很多東西,如果您仍然感到困惑,您將有更多細節帶回給我們。

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