Dot-Htaccess

Apache - 自定義錯誤頁面返回錯誤 AH01071 僅適用於文件請求

  • September 11, 2019

我有一個由共享託管服務提供商託管的網站。它是一個帶有 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 並不會改變症狀。

任何想法是什麼原因造成的?我看到的資訊表明可能會ProxyPassProxyErrorOverride可能會解決問題,但我不知道在哪裡進行設置。

為了記錄,這裡是完整的 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 處理程序來提供錯誤文件。

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