通過 URL Rewrite Module 組件
URL Rewrite Module 是一個用於在 ASP.NET Web Forms 或其他基於 IIS 的 Web 應用程序中重寫 URL 的強大工具。這個模塊允許你將複雜的、不易於記憶或不利於搜索引擎優化的 URL 轉換爲更簡潔、更友好的格式。通過 URL 重寫,你可以提高網站的用戶體驗,增強搜索引擎排名,並更好地控制 URL 結構。
URL Rewrite Module 的主要特點包括:
-
規則定義:你可以定義一系列規則,用於匹配傳入的 URL 模式,並將其重寫到新的 URL。這些規則可以基於正則表達式、通配符或其他邏輯進行定義,非常靈活。
-
HTTP 頭和服務器變量:重寫規則可以基於 HTTP 請求頭、服務器變量或其他條件進行匹配和執行。這使得你可以根據特定的請求屬性或上下文來定製 URL 重寫邏輯。
-
重定向和自定義響應:除了簡單的 URL 重寫,你還可以使用 URL Rewrite Module 來定義重定向規則,將用戶從一個 URL 自動轉發到另一個 URL。此外,你還可以發送自定義的 HTTP 響應或中止請求。
-
性能優化:URL 重寫模塊在 IIS 管道中早期階段處理請求,因此它不會對應用程序的性能產生負面影響。相反,通過優化 URL 結構,它可以提高網站的可訪問性和響應速度。
-
集成與擴展性:URL Rewrite Module 與 IIS 緊密集成,可以方便地通過 web.config 文件進行配置和管理。此外,它還支持導入其他 Web 服務器(如 Apache)的重寫規則,方便遷移和集成。
示例
Url Rewite 官網 下載 URL Rewrite Module 2.1 並安裝
{HTTP_REFERER} 模式爲: ^http://localhost/.*$
, 意思是 請求 HTTP_REFERER 必須包含 http://localhost/ 字符,規則當然是根據自己的情況寫。
添加保存後,站點的 web.config 文件的 system.webServer 節點下就多了 rewrite 節點,配置如下。
<system.webServer>
<rewrite>
<rules>
<rule name="防盜鏈" stopProcessing="true">
<match url=".*\.(gif|jpg|png)" />
<!--<action type="Redirect" url="http://www.baidu.com" />-->
<action type="CustomResponse" statusCode="403" subStatusCode="403" statusReason="Please do not steal my pictures" statusDescription="Please do not steal my pictures" />
<conditions>
<add input="{HTTP_REFERER}" pattern="^http://localhost/.*$" negate="true" />
</conditions>
</rule>
</rules>
</rewrite>
</system.webServer>
效果
自定義 HttpModule 處理
在 ASP.NET 中,HttpModule 是一個用於處理 HTTP 請求和響應的重要組件。通過實現 IHttpModule 接口並定義 Init 和 Dispose 方法,你可以創建自定義的 HttpModule,並在 ASP.NET 請求處理管道中的不同階段插入自定義邏輯。
HttpModule 的主要作用包括:
-
請求和響應處理:你可以在請求到達頁面或處理程序之前或之後執行自定義代碼,例如添加 HTTP 頭、修改響應內容、執行身份驗證或授權邏輯等。
-
事件處理:HttpModule 可以訂閱 HttpApplication 對象上的各種事件,如 BeginRequest、EndRequest、AuthenticateRequest 等,以便在請求處理的不同階段執行代碼。
-
全局功能:由於 HttpModule 在整個 ASP.NET 應用程序中都是全局的,因此它們非常適合用於實現跨多個頁面或處理程序的通用功能。
-
性能監控和日誌記錄:你可以使用 HttpModule 來監控應用程序的性能,記錄請求和響應的詳細信息,以便進行故障排除和性能優化。
在 ASP.NET 中,HttpModule 通過訂閱 HttpApplication 對象的事件來參與請求處理管道的不同階段。這些事件允許你在請求的生命週期中的特定點執行自定義邏輯。以下是一些 HttpApplication 事件,你可以在 HttpModule 的 Init 方法中訂閱它們:
-
BeginRequest:當 ASP.NET 接收到一個新的 HTTP 請求時觸發。這是處理請求的最早階段,可以在此階段執行諸如 URL 重寫、請求驗證或日誌記錄等操作。
-
AuthenticateRequest:在 ASP.NET 對請求進行身份驗證時觸發。通常在此階段使用配置的身份驗證模塊來確定用戶的身份。
-
PostAuthenticateRequest:在身份驗證過程完成後觸發。可以在此階段訪問身份驗證的結果或執行與身份驗證相關的後處理邏輯。
-
AuthorizeRequest:在 ASP.NET 對請求進行授權時觸發。在此階段,可以基於用戶的身份或其他條件確定是否允許訪問請求的資源。
-
PostAuthorizeRequest:在授權過程完成後觸發。可以在此階段訪問授權的結果或執行與授權相關的後處理邏輯。
-
ResolveRequestCache:在 ASP.NET 嘗試從緩存中獲取請求的響應時觸發。如果請求的內容已經在緩存中,則可以直接從緩存中提供響應,而無需執行後續的處理程序。
-
PostResolveRequestCache:在檢查緩存並確定是否使用緩存響應後觸發。無論是否使用了緩存,都會觸發此事件。
-
MapRequestHandler:在 ASP.NET 確定要處理請求的 HTTP 處理程序時觸發。這通常涉及根據請求的 URL 和配置映射到適當的處理程序。
-
PostMapRequestHandler:在映射處理程序後觸發。可以在此階段訪問選定的處理程序或執行與處理程序選擇相關的後處理邏輯。
-
AcquireRequestState:在 ASP.NET 獲取與當前請求關聯的狀態(如會話狀態)時觸發。這是處理與會話或應用程序狀態相關的邏輯的好地方。
-
PostAcquireRequestState:在獲取請求狀態後觸發。可以在此階段訪問請求狀態或執行與狀態獲取相關的後處理邏輯。
-
PreRequestHandlerExecute:在 ASP.NET 開始執行選定的 HTTP 處理程序之前觸發。這是準備請求數據或執行其他預處理邏輯的最後機會。
-
PostRequestHandlerExecute:在 HTTP 處理程序執行後觸發。可以在此階段訪問處理程序的輸出或執行與處理程序執行相關的後處理邏輯。
-
ReleaseRequestState:在 ASP.NET 釋放與當前請求關聯的狀態時觸發。這是清理與狀態相關的資源的好時機。
-
PostReleaseRequestState:在釋放請求狀態後觸發。可以在此階段執行與狀態釋放相關的後處理邏輯。
-
UpdateRequestCache:如果請求的響應可以被緩存,則在發送響應到客戶端之前觸發。可以在此階段將響應添加到緩存中,以便後續請求可以直接從緩存中獲取。
-
EndRequest:在 ASP.NET 完成請求處理並將響應發送到客戶端(或緩存)後觸發。這是執行清理操作或記錄請求結束時間的最後機會。
-
Error:在處理 HTTP 請求的過程中,如果出現未處理的異常,將觸發此事件。可以在此階段記錄錯誤、執行錯誤處理邏輯或重定向到錯誤頁面。
示例
修改 web.config 配置文件
<system.webServer>
<modules>
<add name="antiTheftChainModule" type="AntiTheftChain.AntiTheftChainModule,AntiTheftChain" />
</modules>
</system.webServer>
創建實現 IHttpModule 接口的 AntiTheftChainModule 類
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
namespace AntiTheftChain
{
public class AntiTheftChainModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += Context_BeginRequest;
}
private void Context_BeginRequest(object sender, EventArgs e)
{
HttpApplication context = (HttpApplication)sender;
var regex = new Regex(@"/[^/]+(.jpg|.bmp|.gif|.png)");
var request = context.Context.Request;
if (!regex.IsMatch(request.RawUrl)) return;
if (request.UrlReferrer == null || !"127.0.0.1".Equals(request.UrlReferrer.Host))
{
context.Response.StatusCode = 403;
context.Response.StatusDescription = "(IHttpModule) Please do not steal my pictures";
context.Context.Response.End();
return;
}
var fileName = context.Context.Server.MapPath(request.FilePath);
context.Context.Response.WriteFile(fileName);
}
}
}
效果
自定義 HttpHandler 處理
HttpHandler 是 ASP.NET 中的一個重要組件,負責處理 HTTP 請求。它實際上是 ISAPI 的擴展,處於 HTTP 請求處理的最底層,負責實現具體的請求響應邏輯。
當一個 HTTP 請求通過 HttpModule 容器傳遞到 HttpHandler 容器中時,ASP.NET Framework 會調用 HttpHandler 的 ProcessRequest 成員方法來對這個請求進行真正的處理。HttpHandler 能夠處理一種或多種類型的文件或資源,其處理邏輯是通過實現 IHttpHandler 接口來定義的。
在 ASP.NET 中,創建的 ASP.NET 頁面(如.aspx 文件)通常會被視爲 HttpHandler,因爲它們實現了 IHttpHandler 接口,並最終負責生成 HTTP 響應。然而,有時我們可能需要處理非 HTML 類型的響應,如 XML 數據或圖片等,這時就可以通過自定義 HttpHandler 來實現。
自定義 HttpHandler 能夠讓你更靈活地控制請求的處理方式,實現更復雜的業務邏輯。例如,你可以創建一個自定義的 HttpHandler 來處理特定的文件類型,或者在處理請求之前進行身份驗證和授權檢查。
此外,HttpHandler 還提供了對 HTTP 請求和響應的完全控制,包括讀取請求頭、請求體、查詢字符串等信息,以及設置響應狀態碼、響應頭、響應體等。這使得 HttpHandler 在處理複雜的 HTTP 請求和生成自定義的 HTTP 響應時非常有用。
總的來說,HttpHandler 是 ASP.NET 中處理 HTTP 請求的核心組件,通過實現 IHttpHandler 接口並定義處理邏輯,我們可以實現對 HTTP 請求的靈活處理和自定義響應的生成。
示例
修改 web.config 配置文件
<system.webServer>
<handlers>
<add name="antiTheftChainHandler" path="*.jpg" verb="*" type="AntiTheftChain.AntiTheftChainHandler,AntiTheftChain" />
</handlers>
</system.webServer>
創建實現 IHttpHandler 接口的 AntiTheftChainHandler 類
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace AntiTheftChain
{
public class AntiTheftChainHandler : IHttpHandler
{
public const string ImgHost = "127.0.0.1";
public bool IsReusable => true;
public void ProcessRequest(HttpContext context)
{
var response = context.Response;
var request = context.Request; if (request.UrlReferrer == null || !ImgHost.Equals(request.UrlReferrer.Host))
{
context.Response.StatusCode = 403;
context.Response.StatusDescription = "(IHttpHandler) Please do not steal my pictures";
response.End();
return;
}
var fileName = context.Server.MapPath(request.FilePath);
response.WriteFile(fileName);
if (request.UrlReferrer == null || ImgHost.Equals(request.UrlReferrer.Host))
{
response.WriteFile(fileName);
}
else
{
context.Response.StatusCode = 403;
context.Response.StatusDescription = "(IHttpHandler) Please do not steal my pictures";
response.End();
}
}
}
}
效果
HttpModule 和 HttpHandler 的區別
HttpModule 和 HttpHandler 在 ASP.NET 中各自扮演不同的角色,它們之間的主要區別體現在以下方面:
- 功能和職責:
- HttpModule:它主要作爲 HTTP 請求的“必經之路”,位於請求處理管道中。HttpModule 可以在請求傳遞到最終的 HttpHandler 之前執行一些額外的操作,如安全檢查、日誌記錄等。它也可以在某些條件下終止滿足特定條件的請求,起到了過濾器的作用。每個 HTTP 請求都會逐一通過每個 HttpModule。
- HttpHandler:它是頁面請求的最終處理中心,負責處理具體的工作。每個請求最終都會交給 HttpHandler 的 ProcessRequest()方法進行處理。HttpHandler 針對不同類型的請求提供不同的處理方式。
- 配置和使用:
- HttpModule 的配置可以指定類名和命名空間,並且可以有多個,每個都可以訂閱管道事件中的任意事件,以實現自定義功能。
- HttpHandler 的配置則涉及可訪問的文件、命名空間以及文件類型等。它更類似於 WebForm,可以指定訪問特定頁面的特定方法。
- 作用範圍:
- HttpModule 相當於 Global,它的定義的方法會被所有的頁面訪問到。
- HttpHandler 則針對每一種類型的請求只有一種處理方式,是覆蓋關係。
總結來說,HttpModule 和 HttpHandler 在 ASP.NET 中協同工作,共同處理 HTTP 請求。HttpModule 作爲過濾器,在請求處理之前進行預處理和條件判斷;而 HttpHandler 則作爲請求的最終處理中心,負責實現具體的請求響應邏輯。兩者在配置、使用和作用範圍上也有所不同,但共同構成了 ASP.NET 請求處理的關鍵部分。