Apache - 自定義錯誤頁面返回錯誤 AH01071 僅適用於文件請求
我有一個由共享託管服務提供商託管的網站。它是一個帶有 FPM/FastCGI 和 PHP 7.2 的 Apache
作為共享主機,我可以訪問的唯一配置是 htaccess,但顯然不是任何 Apache conf 文件。
我在我的 htaccess 中配置了一個自定義錯誤頁面,如下所示
ErrorDocument 404 /error404.php
:今天我注意到我的自定義錯誤 404 頁面沒有顯示。而是將純文字File not found.
返回到瀏覽器,並在標題中顯示狀態程式碼 404。進一步調查顯示,這僅在請求文件時才會發生。如果您請求一個不存在的目錄,那麼您將獲得自定義錯誤頁面!例如,請求mydomain.info/dummy.htm
給出錯誤但請求mydomain.info/dummy/
返回自定義錯誤頁面。伺服器正在記錄每個錯誤
AH01071
的錯誤。Primary script unknown``File not found.
似乎在伺服器上啟用了 ModSecurity,因為日誌記錄了被拒絕的惡意請求,例如
[client xxx.xxx.xxx.xxx] ModSecurity: Access denied with code 403 (phase 2). ... etc
此外,我最近按照託管服務提供商的建議更改為 PHP 7.2。不過,改回 5.6 並不會改變症狀。
任何想法是什麼原因造成的?我看到的資訊表明可能會
ProxyPass
或ProxyErrorOverride
可能會解決問題,但我不知道在哪裡進行設置。為了記錄,這裡是完整的 htaccess,疣和所有:
RewriteEngine on # AddType TYPE/SUBTYPE EXTENSION AddType audio/mpeg mp3 AddType video/mp4 mp4 m4v # Add WWW RewriteCond %{HTTP_HOST} ^mydomain\.info [NC] RewriteRule ^(.*) https://www.mydomain.info/$1 [R=301,L,NE] # Redirect for .COM RewriteCond %{HTTP_HOST} mydomain\.com$ [NC] RewriteRule ^/?(.*) https://www.mydomain.info/$1 [R=301,L,NE] # Force HTTPS RewriteEngine On RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE] # Home page canonicalization RewriteCond %{THE_REQUEST} ^.*\/index\.htm\ HTTP/ RewriteRule ^(.*)index\.htm$ /$1 [R=301,L,NE] # Removed page_missing.htm Redirect 301 /page_missing.htm /new_page.htm#section_b # Some content moved to sub-folder Redirect 301 /extra_content.htm /extra/extra_content.htm # Internally redirect all HTM & HTML URLs to PHP RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)\.(htm|html)$ /$1\.php # Error 404 page ErrorDocument 404 /error404.php <IfModule mod_expires.c> # Activate mod_expires for this directory ExpiresActive on # Default ExpiresDefault "access plus 7 days" # Default for actual documents ExpiresByType text/html "access plus 15 minutes" # cache CSS files for 7 days ExpiresByType text/css "access plus 7 days" # locally cache common resource types for 7 days ExpiresByType image/jpg "access plus 7 days" ExpiresByType image/jpeg "access plus 7 days" ExpiresByType image/gif "access plus 7 days" ExpiresByType image/png "access plus 7 days" ExpiresByType application/pdf "access plus 7 days" ExpiresByType audio/mpeg "access plus 7 days" </IfModule>
# Internally redirect all HTM & HTML URLs to PHP RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)\.(htm|html)$ /$1\.php
我不一定期望這會導致您遇到的問題,但是,您有指令“盲目地”將任何不存在的
.htm
(或.html
)請求重寫到等效.php
文件,無論該.php
文件是否存在。(錯誤文件應該會擷取失去的.php
文件,而不是.htm
最初請求的失去文件。)這也可以解釋您在請求不存在的“目錄”(即表單的請求
/dummy/
)時所看到的行為差異,該請求不會被上述指令重寫並且似乎按預期“工作”(即。呼叫自定義錯誤文件)。您可以將上述規則修改為僅
.php
在文件存在時才重寫。例如:# Internally redirect all HTM & HTML URLs to PHP RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{DOCUMENT_ROOT}/$1.php -f RewriteRule ^(.*)\.(htm|html)$ /$1.php [L]
無需轉義
RewriteRule
替換中的文字點。您應該包含該L
標誌(儘管它目前是最後一個 mod_rewrite 指令,所以嚴格來說並不重要)。**更新:**如果您請求一個不存在的 php 頁面,那麼您仍然會收到“找不到文件”響應。
這聽起來像是伺服器配置問題。您可以通過手動重寫錯誤文件來“解決”此問題:
RewriteCond %{REQUEST_FILENAME} !-f RewriteRule \.php$ /error404.php [L]
儘管您可能需要進行修改
error404.php
以解決此問題。或者……我也很好奇從 Apache 觸發 404 (從表面上看,這似乎沒有太大意義)會改變這種行為。例如,代替上面的重寫:
RewriteCond %{REQUEST_FILENAME} !-f RewriteRule \.php$ - [R=404]
這種方法背後的想法是,它有望在將請求傳遞給 PHP 處理程序之前觸發錯誤文件的內部子請求(這似乎與錯誤文件衝突)。然後只呼叫 PHP 處理程序來提供錯誤文件。