Apache HTTPD 2.4.x:如果 URL/URI 中存在某些字元,如何將使用者“引導”到自定義錯誤頁面?
所以我有這個 apache 配置,我試圖將使用者“重寫”到自定義錯誤頁面,但它不起作用。我
http://localhost/index.html/ddgdg%:sdsdfs
在瀏覽器中輸入,我沒有得到我的錯誤頁面。
http://localhost/my-error.html
我可以通過在瀏覽器 ( )中直接輸入其 URL 來查看自定義錯誤頁面。有什麼想法我可能做錯了嗎?
我的完整 httpd.conf:連結到 httpd.conf
我對預設 httpd.conf 的更改(我還必須取消對 mod_rewrite.so 的 LoadModule 的註釋)
RewriteEngine On LogLevel alert rewrite:info #if invalid characters are present in the URI, display 404 page RewriteCond %{REQUEST_URI} ^\/.+[:%].+ RewriteRule "^/$" "http://%{SERVER_NAME}/my-error.html" [L,R=301]
自定義錯誤頁面的內容
$ cat /Library/WebServer/Documents/my-error.html <html><body><h1>404 error here</h1></body></html>
阿帕奇版本
$ apachectl -v Server version: Apache/2.4.34 (Unix) Server built: Feb 22 2019 20:20:11
**編輯1:**目前正在執行 macOS Mojave,但會在一段時間內設置一個 Ubuntu VM。
這裡有幾個不同的問題……
http://localhost/index.html/ddgdg%:sdsdfs
你實際上並沒有說明你得到了什麼回應,只是沒有發生什麼。但是,由於雜散
%
(不在十六進制編碼的八位字節之前),這個 URL 是嚴格無效的,我希望 Apache 以400 Bad Request
. 覆蓋此問題的唯一方法是創建自定義 400 錯誤文件,您可以在其中檢查請求的 URL 並自定義響應。例如:ErrorDocument 400 /my-error.html
如果不是因為流浪
%
,您應該能夠使用 mod_rewrite 擷取此請求並相應地重定向。但是,您RewriteRule
正在檢查一個空的 URL 路徑(即。"^/$"
),而您的範例中請求的 URL 遠非空(即。/index.html/ddgdg%:sdsdfs
) - 因此該RewriteRule
指令永遠不會與您的範例 URL 匹配。要檢查URL 路徑中%
的:
任何位置並重定向,您可以執行以下操作:# Checks for a "%" or ":" in the URL-path RewriteRule [%:] /my-error.html [L,R=302]
但請注意,
RewriteRule
模式匹配的 URL 路徑(以及REQUEST_URI
伺服器變數)已經被 % 解碼,所以這只會匹配特殊字元被雙重編碼(罕見)的 URL。(如上所述,在mod_rewrite 能夠處理請求之前%
,否則可能會產生 400 響應。)我還會質疑您為什麼要“重定向”到您的自定義錯誤文件(即。
my-error.html
)而不是直接提供它?重定向有許多缺點:向客戶端發送 3xx 響應、失去有關導致錯誤的 URL 的資訊、對伺服器的請求加倍等。您可以通過簡單地刪除標誌在內部將請求重寫
/my-error.html
為,而不是重定向。R
例如:RewriteRule [%:] /my-error.html [L]
但是,除非您手動設置 HTTP 狀態,否則
my-error.html
使用者將看到200 OK
響應 - 這是不可取的。或者(最好)創建一個自定義 404(看起來像你想要做的)並觸發它。例如:
ErrorDocument 404 /my-error.html RewriteRule [%:] - [R=404]
Apache 然後設置“404 Not Found”HTTP 響應狀態。
但是,您可能根本不需要在這裡使用 mod_rewrite。在您的範例 URL 中,
index.html
URL 路徑中的所有內容,即/ddgdg%:sdsdfs
,都是附加路徑名資訊(又名 path-info /PATH_INFO
)。預設情況下,處理 text/html 響應的處理程序不允許路徑資訊,並將隱式觸發 404(如果它不是用於流浪%
- 如上所述),呼叫您的自定義ErrorDocument
(如果已定義)。因此,RewriteRule
可以簡單地刪除最後一個範例中的指令,因為 Apache 無論如何都會觸發 404(除非您使用 覆蓋此行為AcceptPathInfo
)。