URL重寫(URL Rewriting)是一種REST的相關技術,它可以在Web Server中,針對使用者所提供的URL進行轉換後,再傳入Web Server中的程式處理器。
範例:
最常見的用法,就是將一組URL階層字串,轉換成帶有查詢字串(query string)的URL,或是反向轉換,例如: http://www.somebloghost.com/Blogs/Posts.aspx?Year=2006&Month=12&Day=10
經過URL重寫後,可以變成:http://www.somebloghost.com/Blogs/2006/12/10/
另一個例子,下面的URL:http://www.somehost.com/Blogs/2006/12/
經過URL重寫後,可轉換成:http://www.somehost.com/Blogs.aspx?year=2006&month=12
因此,使用者可以使用較直覺的方式來輸入URL(這也是REST的主要目的),是搜尋引擎最佳化(SEO)的作法之一。而應用程式開發者可以利用這個機制來將參數隱藏起來,可避免讓網路上的惡意使用者收集到有利於發動攻擊的資訊。
URL重新導向(URL Redirect)和URL重寫之間在措辭上的區別很細微,但對於向客戶端提供資源具有重要意義。ASP.NET Core的URL重寫Middleware能夠滿足這兩種需求。
要使用URL重寫,就要在Startup.cs中的Configure()中使用UseReWrite這個Middleware
現在就來實作範例
首先一樣延用之前的的範例Starup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
var options = new RewriteOptions()
.AddRewrite("Post.aspx", "api/Post", skipRemainingRules: true)
.AddRedirect("Post.php", "api/Post");
app.UseRewriter(options);
app.UseRouting();
...
}
注意:app.UseRewriter()順序要在app.UseRouting()前面才能作用
AddRewrite()是進行URL重寫
AddRedirect()則是進行URL重新導向
我們可以透過chrome的開發者工具看到差異
這是使用AddRewrite()的範例
可以看到AddRewrite()會把目標的URL當作有效資源,並將指定路徑的資源回傳。
這是AddRedirect()的範例
可以看到AddRedirect()的方式,會使用HTTP 302的方式在導向指定的路徑
在這邊說明一下Http 301 與 302 的差異
301 永久性轉址
302 暫時性轉址
在一般操作上,這兩種方式是沒有差異的,差異就在對SEO的影響
通過設定301重新導向,你可以告訴Google你的舊網址已經無效了,你希望搜尋引擎能夠將舊網址的流量轉移到新的URL頁面。此時搜尋引擎就會將舊網址的所有流量與排名一併的轉移到新的網址。
302重新導向常用於A/B測試或是有短期的活動頁面而使用的。他會將原本的URL導向另一個URL,但是不會讓google的排名效果下降。不過如果時間拉長,長期使用302做導向的話,SEO的分數還是會受到影響!
AddRedirect()也提供了方法多載,可以在第三個參數輸入需要的Http Status Code
將上方的範例修改成
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
var options = new RewriteOptions()
.AddRewrite("Post.aspx", "api/Post", skipRemainingRules: true)
.AddRedirect("Post.php", "api/Post", 301);
app.UseRewriter(options);
app.UseRouting();
...
}
就可看到原本的HTTP 302變成301了
以圖片來解釋 URL重寫 與 URL重新導向 的差異
圖片來源:ASP.NET Core 的 URL 重寫中介軟體
首先看到URL重新導向的方式,用戶先向Server發出Request,Server會回傳一個302的code,並指定導向到某個URL,然後用戶端再發一次Request去Server進行呼叫,所以會向伺服器發出兩次的Request
圖片來源:ASP.NET Core 的 URL 重寫中介軟體
接著看到URL重寫,用戶發出Request,Server直接從重寫URL的地方回應資源給用戶端。用戶只會發出一次Request,但是沒辦法在發出request與接收Response的時候知道資源位於哪個URL。
下方範例就把一般URL階層字串,轉換成帶有查詢字串(query string)的URL
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
var options = new RewriteOptions()
.AddRedirect("^api/Post/(.*)/(.*)", "api/Post?id=$1&id2=$2", 301);
app.UseRewriter(options);
app.UseRouting();
...
}
呼叫 https://localhost:5001/api/Post/1/2
的時候
會將路徑轉導到 https://localhost:5001/api/Post?id=1&id=2
透過Regex可以很彈性的去操作URL重寫與URL重新導向,增加了很多便利性。