偽靜態將動態查詢字串(?id=1)轉為靜態風格 URL(/news_1.html),提升 SEO、隱藏參數結構、降低 SQL 注入風險。本文示範基於 IHttpModule 的全域攔截重寫方案。
IHttpModule,在 Init(HttpApplication context) 訂閱 BeginRequest 事件。BeginRequest 中解析 HttpContext.Current.Request,匹配偽靜態規則。context.RewritePath("真實路徑?參數") 內部重導向,瀏覽器 URL 不變。web.config <httpModules> (IIS 6/經典模式) 或 <system.webServer><modules> (IIS 7+ 整合模式)。public class UrlRewriteModule : IHttpModule {
public void Init(HttpApplication context) {
context.BeginRequest += OnBeginRequest;
}
private void OnBeginRequest(object sender, EventArgs e) {
var app = (HttpApplication)sender;
var ctx = app.Context;
var path = ctx.Request.Path.ToLowerInvariant(); // 如 /news_123.html
// 規則:/news_{id}.html → /news.aspx?id={id}
var match = Regex.Match(path, @"/news_(\d+)\.html$");
if (match.Success) {
var id = match.Groups[1].Value;
ctx.RewritePath($"/news.aspx?id={id}"); // 內部轉發,保持瀏覽器 URL
return;
}
// 更多規則:/product/{category}/{id}.html 等...
}
public void Dispose() { }
}
<!-- IIS 6 / 經典模式 -->
<system.web>
<httpModules>
<add name="UrlRewriteModule" type="MyNamespace.UrlRewriteModule, MyAssembly" />
</httpModules>
</system.web>
<!-- IIS 7+ 整合模式(建議) -->
<system.webServer>
<modules>
<add name="UrlRewriteModule" type="MyNamespace.UrlRewriteModule, MyAssembly"
preCondition="managedHandler" />
</modules>
</system.webServer>
<rewriteRules>
<add pattern="^/news_(\d+)\.html$" rewrite="/news.aspx?id=$1" />
<add pattern="^/product/([\w-]+)/(\d+)\.html$" rewrite="/product.aspx?cat=$1&id=$2" />
</rewriteRules>
// 模組讀取配置,動態編譯 Regex,支援熱更新
var rules = ConfigHelper.GetRewriteRules();
foreach (var rule in rules) {
if (rule.Regex.IsMatch(path)) {
var newPath = rule.Regex.Replace(path, rule.Rewrite);
ctx.RewritePath(newPath);
break;
}
}
| 方案 | 原理 | 優點 | 缺點 |
|---|---|---|---|
| IHttpModule (本文) | ASP.NET 管線內重寫 | 代碼控制靈活、無額外依賴、支援複雜邏輯 | 需開發維護、僅限 ASP.NET 應用 |
| IIS URL Rewrite Module | 原生 C++ 模組,XML 配置 | 效能極高、支援出站重寫、SEO 元標籤、無代碼 | 規則複雜時 XML 難維護、無法執行 C# 邏輯 |
| ASP.NET Routing (MVC/WebForms 4+) | RouteTable 映射 | 雙向生成 URL、強型別參數、MVC 原生 | 僅限路由匹配、非全域攔截 |
| 真靜態生成 | 定時/觸發生成 .html 檔案 | 極致效能、零動態查詢 | 資料實時性差、部署複雜、動態互動受限 |
RewritePath 不會改變瀏覽器地址欄(Server-side),若需客戶端跳轉用 Response.Redirect (302)。preCondition="managedHandler" 或在模組開頭排除靜態副檔名。Form.Action 仍為原始路徑,可能導致偽靜態 URL 變動態,需在 MasterPage/基類修正 form.Action = Request.RawUrl。