當前位置:
首頁 > 最新 > ASP.NET Core URL Rewrite中間件

ASP.NET Core URL Rewrite中間件

URL重寫是基於一個或多個預置規則修改請求URL的行為。URL重寫在資源位置和訪問地址之間創建了一種抽象,這樣二者之間就減少了緊密的聯繫。URL重寫有多種適用的場景:

臨時或永久移動或替換伺服器資源,同時為這些資源保持穩定的訪問

為不同應用程序或同一個應用程序的不同區域的拆分請求處理

根據請求移除、添加、重新組織URL段(segment)

SEO優化

允許使用友好的公共URL來幫助人們通過鏈接預測找到內容

將不安全的請求重定向到安全端點

圖片防盜鏈

可以通過多種方式定義改變URL的規則,包括正則表達式、Apache mod_rewrite模塊規則、IIS重寫模塊規則和自定義規則邏輯。本文介紹URL重寫及說明如何在ASP.NET Core應用中使用URL重寫中間件。

注意:URL重寫可能會降低應用的性能,您應該儘可能的限制規則的數量和規則的複雜性。

URL重定向和URL重寫

從字面意思上看URL重定向和URL重寫的差異並不明顯,但二者在提供資源給客戶端方面都有重要意義。ASP.NET Core的URL重寫中間件能夠同時滿足二者的需求。URL重定向是客戶端操作,指示客戶端在另一個地址訪問資源,需要額外往返伺服器。當客戶端對資源發出請求時,返回到客戶端的重定向URL將顯示在瀏覽器的地址欄中。例如/resource被重定向到/different-resource時:客戶端請求/resource,服務端響應客戶端應在/different-resource獲取資源,其響應的狀態碼會指示重定向是臨時的還是永久的,然後客戶端會向/different-resource發送一個新請求獲取資源。

將請求重定向到其他URL時,可以指定重定向是永久還是臨時。301(Moved Permanently)狀態代碼用於表明資源具有新的永久URL,並且希望客戶端將來對該資源的所有請求都應使用新URL。當收到301狀態碼時客戶端可以緩存響應。302(Found)狀態碼用於臨時重定向,所以客戶端不應該存儲和重用該URL。狀態碼的含義請參考這裡。URL重寫是伺服器端操作,用於從不同的資源地址提供資源。URL重寫不需要額外的往返伺服器,並且重寫後的URL不會返回給客戶端,也不會出現在客戶端的地址欄中。當/resource被重寫為/different-resource時:客戶端請求/resource,服務端在內部從/different-resource獲取資源並響應給客戶端。儘管客戶端也許可以從重寫後的URL處獲取資源,但客戶端並不會收到資源存在於重寫後URL的通知。

何時使用URL重寫中間件

當無法在Windows Server上使用IIS重寫模塊、Apache伺服器上的Apache mod_rewrite模塊、Nginx上的URL重寫或應用程序託管在HTTP.sys伺服器(以前稱為WebListener)上時,請使用URL重寫中間件。推薦在IIS,Apache或Nginx中使用基於伺服器的URL重寫技術的主要原因是中間件不支持這些模塊的全部功能,並且中間件的性能可能無法達到這些模塊的性能。但是,這些伺服器重寫模塊的某些功能不適用於ASP.NET Core項目,例如IIS Rewrite模塊的IsFile和IsDirectory。在這些情況下,請改用中間件。

包引用

要在項目中使用URL重寫中間件,請添加Microsoft.AspNetCore.Rewrite包的引用。該功能適用於ASP.NET Core 1.1或更高版本的應用程序。

配置重寫及重定向規則

通過RewriteOptions類實例的擴展方法來建立URL重寫和重定向規則,按照你希望處理的順序將這些規則鏈接起來,然後通過使用app.UseRewriter(options)將URL重寫選項傳遞到請求管道,以下是幾種重寫、重定向的配置代碼,後面會針對每種配置單獨解釋:

URL重定向

使用AddRedirect方法重定向請求,第一個參數為匹配請求URL的正則表達式,第二個參數為替換的文本,第三個參數(如果存在)指定狀態碼,如果未指定狀態碼,默認為302(Found)。

打開瀏覽器的開發者工具,向/redirect-rule/1234/5678發送一個請求。重定向規則中的正則表達式將匹配請求路徑,將路徑替換為/redirected/1234/5678,服務端將重定向URL和302(Found)狀態代碼發送回客戶端。客戶端基於該URL發送新請求並將該URL顯示到地址欄中,然後客戶端收到一個200(OK)的響應。

警告:新建重定向規則時一定要謹慎,重定向規則將會對應用每一個請求都進行匹配,包括重定向後的URL。所以很容易不小心創建一個無限重定向循環。

發送一個請求:/redirect-rule/1234/5678,響應如下圖:

重定向規則中正則表達式括弧內的部分稱為捕獲組,表達式中點(.)的含義是匹配任何字元,星號(*)表示匹配之前的字元零次或者多次。因此,URL中最後兩段/123/5678被(.*)捕獲組所捕獲,URL中位於redirect-rule/之後的任何值都將會被該組捕獲。

在替換字元串中,捕獲組將捕獲的內容注入到($n)符號所在位置,其中$後的數字n代表捕獲的序列號。第一個捕獲組是$1,第二個是$2,以此類推。在上面的例子中,重定向規則中的正則表達式只有一個捕獲組,所以替換字元串中只有一個$1,最終/redirect-rule/1234/5678被替換為/redirect-rule/1234/5678。

URL重定向到安全站點

可使用AddRedirectToHttps方法將不安全的請求重定向到具有安全HTTPS協議的同一主機和路徑,如果未提供狀態碼參數,中間件將使用默認值302(Found)。如果未提供埠號參數,中間件使用默認值null,這意味著客戶端將使用https協議同時從443埠訪問資源,下面的代碼片段演示如何將重定向狀態碼設為301(Moved Permanently),同時將埠設為5001:

也可以使用AddRedirectToHttpsPermanent方法將不安全的請求重定向到具有安全HTTPS協議的同一主機和路徑(埠443上的https://)。中間件將響應狀態碼設置為301(Moved Permanently)。

注意:在不需要其他重定向規則的情況下重定向到HTTPS時,建議使用HTTPS重定向中間件。請參考這裡

URL重寫

可使用AddRewrite方法創建重寫規則,第一個參數為匹配請求URL的正則表達式,第二個參數是替換字元串,第三個參數skipRemainingRules: ,表示如果當前規則生效是否要跳過其它的重寫規則。

發送一個請求:/rewrite-rule/1234/5678,重定向請求及響應如下圖:

我們注意到正則表達式開頭是字元^,它的含義是匹配需要從URL路徑的開頭開始。在之前重定向例子中,正則表達式的開頭並沒有字元^,因此,路徑中redirect-rule/之前的任何字元都可以成功匹配。

在重寫規則中,正則表達式^rewrite-rule/(d+)/(d+)僅匹配以rewrite-rule/開頭的路徑,請注意二者之間的區別:

在正則表達式^rewrite-rule/(d+)/(d+)中有兩個捕獲組:(d+)/(d+),d表示匹配一個數字,加號(+)表示匹配之前的字元1次或者多次。因此,匹配的URL必須包含一個數字,後跟一個正斜杠,後跟另一個數字。捕獲的內容將會被分別注入到重寫字元串中的$1和$2位置。所以請求URL/rewrite-rule/1234/5678將會被重寫為/rewritten?var1=1234&var2=5678。如果原始請求中存在查詢字元串,則在重寫URL時會保留該查詢字元串。URL重寫不會有額外的伺服器往返。如果資源存在,服務端獲取資源內容並返回給客戶端200(OK)狀態碼。因為客戶端沒有被重定向,所以瀏覽器地址欄中的地址不會改變。就客戶端而言,是感知不到URL重寫的。

注意:儘可能使用skipRemainingRules:true參數,因為匹配規則是一個昂貴的過程並增加了應用程序響應時間。為了更快的響應,請考慮以下建議:

將重寫規則排序:從最常匹配的規則到最不常匹配的規則

規則匹配成功之後跳過剩餘的規則

使用Apache mod_rewrite規則

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 dotNET跨平台 的精彩文章:

NetCore2.1 WebAPI 根據swagger.json自動生成客戶端代碼
要用Identity Server 4-OAuth 2.0 超級簡介

TAG:dotNET跨平台 |