2011-09-20 39 views
2

我正在使用mod_rewrite對每個與現有文件或目錄不匹配的請求進行重寫。這是我的配置:如果路徑上存在文件,Apache不會重寫請求

RewriteEngine On 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^.*$ /index.php [NC,L] 

這是用來像/abc/foo/abc/foo/10到我的應用程序URL映射。它工作得很好。

爲了提高性能,我的應用程序現在存儲調用的結果/abc/foo在文件foo在相應的目錄/abc - 這樣在第一次調用後改寫條件就不再適用(文件不存在)和apache直接提供數據而不必先調用應用程序。工作得很好。

問題是:現在請求/abc/foo/10不再導致URL被重寫,而是出現錯誤「404 File Not Found」。日誌條目指出重寫條件!-f不再爲真,但實際上文件/abc/foo/10確實存在而不是/abc/foo存在,但是一個文件,而不是一個目錄。

我該如何得到這個工作?

(多視圖被禁用)

+0

讓我得到這個正確的,所以當你提出要求'/ ABC /富/ 10',你想要的數據也下/ ABC下FOO被寫入到文件夾一個名爲10的文件?這是你在第二次電話中所期待的嗎? –

+0

不,問題是如果文件'/ abc/foo'存在,調用'/ abc/foo/10'不再匹配'RewriteCond%{REQUEST_FILENAME}!-f'。 – Niko

+0

爲什麼不先把'RewriteCond%{REQUEST_FILENAME}!-d'放入'RewriteCond%{REQUEST_FILENAME}!-f'中,然後看到結果,並且重寫規則^(。*)$而不是^。 * $並直接指向index.php而不是/index.php –

回答

3

您必須在W /對的AcceptPathInfo每DIR/htaccess的上下文。

因此REQUEST_FILENAME匹配存在的部分,與REQUEST_URI不一樣。

如果您不關心請求先前在您的rewritecond中映射的位置,請使用REQUEST_URI var。

在per-vh的情況下,這些變量總是相同的。

+0

我對「AcceptPathInfo」不熟悉,是否有助於停用它? – Niko

4

這是因爲foo作爲文件存在,而apache將foo作爲查詢字符串傳遞給附加/ 10。因此,您的應用程序應該向foo文件寫入一些額外的代碼,該代碼還會檢查請求是否包含一些額外的url組件,然後處理目錄「foo」和文件10的創建。

+0

有沒有機會告訴Apache不要這樣做? – Niko

2

項目設計有點錯誤 - 其他人已經指出它不是可縮放的 - 如果已經有/ abc/foo文件,如何將請求緩存到/ abc/foo/10?

對此和你的問題的答案是使用子文件夾,而不是文件。

所以不是的緩存結構:

/abc/foo 
/abc/bar 
...? 

使用:

/abc/index.html 
/abc/foo/index.html 
/abc/bar/index.html 
/abc/foo/10/index.html 

每一次創建新的目錄中的index.html

這一次的Apache會發現有/ abc/foo文件夾,但不包含/ abc/foo/10文件,因此RewriteCond將應用。

編輯

您也可以嘗試用不同的方式 - 修改與mod_rewrite的URL,改變網址:

/abc/foo 
/abc/bar 
/abc/foo/10 

喜歡的東西:

/cache/abc~foo 
/cache/abc~bar 
/cache/abc~foo~10 

htaccess的規則(約):

# redirecting to cache folder and removing last '/' 
RewriteCond %{REQUEST_URI} ^/(abc|cde) 
RewriteRule ^(.*?)/?$ /cache/$1 [L] 

# recursive replacing '/' with '~' 
RewriteCond %{REQUEST_URI} ^/cache/.*/ 
RewriteRule cache/(.*)/(.*)$ /cache/$1~$2 [L] 

你的標準htaccess的規則應遵循

+0

謝謝!實際上,我已經對整個緩存系統進行了重構,但仍然對Apache爲什麼如此表現感到好奇。 – Niko

相關問題