[鐵人賽Day07] ASP.Net Core MVC 進化之路 - URL複寫(URL Rewrite)

在網站開發的過程中,

更改URL算是還蠻常發生的事,

假設某公司的首頁URL更新了,

使用者卻輸入了舊的URL(可能從書籤列點選連結),

總不能回應404吧?

 

URL Rewrite就是為了解決這個問題。

本篇將介紹ASP.Net Core如何做URL Rewrite。

 

講到URL Rewrite(URL複寫)就不得不提他的雙胞胎兄弟 - URL Redirect(URL轉址),

兩者乍看有點像但本質上又不太一樣。

 

我們來以電話轉接做個比喻,

大部分公司內部的電話都有內碼,

小明原本是公司A部門的員工,

在上週收到人事通知調職到B部門,

你是A部門的員工,

當外線打到A部門找小明時,

你有兩個選擇,

一個是幫他轉接到其他部門,如下圖。

另一個則是告訴他B部門的電話號碼,

並請他在撥一次。

而這恰好就是URL RewriteURL Redirect不同之處。

URL Rewrite:當伺服器收到請求時發現這段URL已經異動過,伺服器會幫你訪問異動後的URL,再將結果回傳給瀏覽器。

URL Redirect:當伺服器收到請求時發現這段URL已經異動過,伺服器會將異動後的URL回傳給瀏覽器(301 or 302),再由瀏覽器重新發送請求至異動後的URL。

簡單來講,如果你做的是URL Rewrite,瀏覽器上仍然會顯示舊的URL。

URL Redirect的話則會由瀏覽器幫你轉址到新的URL,所以瀏覽器上會顯示新的URL。

 

接著之後我們開始實作。

ASP.Net Core的URL Rewrite依舊是以Middleware的形式存在。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    var rewriteOption = new RewriteOptions();
    rewriteOption.AddRewrite("index.aspx", "Home/Index", skipRemainingRules: true);
    rewriteOption.AddRedirect("contact.aspx", "Home/Contact");

    app.UseRewriter(rewriteOption);
    app.UseMvcWithDefaultRoute();
}

rewriteOption中的AddRewrite、AddRedirect分別可以幫我們實現URL Rewrite及URL Redirect,

其中AddRewrite最後一個參數skipRemainingRules,

用來表示當URL符合時是否要略過其他規則,

我們將index.aspx設定為URL Rewrite,實際上內容則跟Home/Index索取。

而contact.aspx則回傳新的URL,由瀏覽器重新訪問Home/Contact。

接著我們進行測試。

 

輸入index.aspx,

發現網址沒變,但畫面是Home/Index的預設內容。

 

輸入contact.aspx。

我們可以透過開發工具查看Request URL及回傳的Status Code

並從Response Headers中查看重新導向後的URL。

 

除此之外也支援Regular Expression,

我們修改一下範例。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    var rewriteOption = new RewriteOptions();
    rewriteOption.AddRewrite("(.*).aspx", "Home/$1", skipRemainingRules: true);
 
    app.UseRewriter(rewriteOption);
    app.UseMvcWithDefaultRoute();
}

 

括號內的區間可表示為變數(代表$1),

改完之後進行測試。

 

如果對正規表達式(Regular Expression)不熟的朋友,

微軟很貼心的附上一些URL Rewrite常用的範例

需要的可以參考看看。

 

參考

https://docs.microsoft.com/zh-tw/aspnet/core/fundamentals/url-rewriting?view=aspnetcore-2.1&tabs=aspnetcore2x#regex-examples