為 ASP.NET Core 程序制作 URL 的 301/302 跳轉
小編:啊南 62閱讀 2020.11.09
如果你有一些需要重定向網頁 URL 的情況,可以返回 HTTP 狀態碼 301/302 告訴瀏覽器或者搜索引擎訪問新的 URL。本文描述如何在 ASP.NET Core 中進行重定向。
HTTP 狀態碼 301/302
301 表示“Moved Permanently”,即永久移動。通過返回此狀態碼可以告知瀏覽器或者搜索引擎此 URL 已經永久移動到了新的 URL 地址。搜索引擎會使用新的 URL 來更新自己的搜索結果,而瀏覽器會將此 URL 重定向緩存起來,下次訪問的時候直接使用新的 URL 來訪問。
302 表示“Found”,發現;原始描述為“Moved Temporarily”,即臨時移動。通過返回此狀態碼可以告知瀏覽器或者搜索引擎此 URL 臨時移動到了新的 URL 地址。搜索引擎會使用此新的 URL 來抓取頁面的內容但不會更新此 URL,而瀏覽器會訪問新的 URL 但不會緩存此 URL 重定向。
還有其他的重定向的 HTTP 狀態碼:
- 303 See Other
- 307 Temporary Redirect
- 308 Permanent Redirect
301/302 本來設計為移動資源的時候保持方法不變,但各大瀏覽器在實現的時候對于 POST 方法,有的實現成了 GET 方法,有的實現成了 POST 方法。于是在后來的 HTTP 標準中將瀏覽器的錯誤實現變成了標準,301 和 302 方法要求使用 GET 方法重定向。不過由于歷史原因無法保證一定是改用 GET 方法,所以增加了 303 狀態碼要求一定使用 GET 方法重定向。隨后將原來本應該正確實現的 301 和 302 重新定義成 307 和 308 狀態碼,要求重定向時不允許修改方法。
ASP.NET CoreASP.NET Core 的 Blazor 框架生成的頁面在路由的時候是不識別.html后綴的,而帶有.html后綴的 URL 會被識別為靜態文件。于是,如果創建了一個空的 Blazor 應用,當訪問 https://blog.walterlv.com/post/redirect-middleware-for-asp-dotnet.html 網址的時候,會返回 404 Not Found,而不是路由到我的博客頁面。
如果我們將此 URL 重定向到不帶后綴的 URL,則可以被 Blazor 框架識別并正確顯示對應的博客頁面。
我們有兩個不同的方式來實現這種 URL 的重定向:
- 做一個重定向的控制器Controller,然后在控制器中重定向所有的博客頁面
- 做一個重定向的中間件,對所有包含.html后綴的博客頁面重定向到沒有.html后綴的博客頁面
不過,寫一個Controller會要求這個Controller路由到幾乎所有的 URL 上,對其他功能很不利,所以中間件是最合適的方式。
重定向中間件public class Startup { public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ++ app.UseAutoRemoveHtmlExtension(); app.UseEndpoints(endpoints => { endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); }); app.UseStaticFiles(); } }
在Startup類的Configure方法中可以添加中間件。為了實現去掉.html后綴的中間件,我添加了一個自己的擴展方法UseAutoRemoveHtmlExtension。
/// <summary> /// 自動移除所有的 .html 后綴,并永久重定向到沒有 .html 后綴的網頁。 /// </summary> /// <param name="app"><see cref="IApplicationBuilder"/>。</param> /// <returns><see cref="IApplicationBuilder"/>。</returns> public static IApplicationBuilder UseAutoRemoveHtmlExtension(this IApplicationBuilder app) => app.Use(async (context, next) => { var urlPath = context.Request.Path.HasValue ? context.Request.Path.Value : ""; if (urlPath.EndsWith(".html", StringComparison.OrdinalIgnoreCase)) { // 去掉 .html 后綴 var url = urlPath[0..^5]; context.Response.Redirect(url); context.Response.StatusCode = 301; return; } await next().ConfigureAwait(false); });
實現自己的中間件實際上直接調用IApplicationBuilder中的Use方法即可,傳入一個委托用來在 URL 處理過程中添加一個步驟。
兩個參數,context中包含了本次請求的一些上下文,包括域名、URL 路徑,返回的 HTTP 狀態碼。調用context.Response.Redirect方法可以進行 302 跳轉。如果需要改成 301 跳轉,則直接設置context.Response.StatusCode方法即可。
接下來,對于不需要重定向的網址,我們直接交給后面的中間件處理,調用await next()。
重定向如果你希望做其他種類的跳轉,你也可以添加新的中間件,比如:
- 將 HTTP 重定向到 HTTPS(谷歌建議使用 301 跳轉)
- 你可以在打開某個網頁之前要求登錄,于是做一個 302 跳轉到登錄頁面;
-
你可以將一些已經過時的網頁進行 301 跳轉到新的網頁;
- 比如我將一些之前不太規范的博客 URL 重定向到統一的格式;
- 你可以在遷移服務的時候臨時做一個 302 跳轉。
請注意,301 重定向會被瀏覽器緩存。也就是說如果你重定向到了一個錯誤的網址,那么再次訪問的話瀏覽器將直接訪問這個錯誤的網址。如果希望瀏覽器停止重定向到這個錯誤的網址,需要清除瀏覽器的緩存。所以使用 301 的時候需要謹慎一些。
相關推薦
- ASP.Net Web Page深入探討 一、服務器腳本基礎介紹首先,我們先復習一下Web服務器頁面的基本執行方式:1、 客戶端通過在瀏覽器的地址欄敲入地址來發送請求到服務器端2、 服務器接收到請求之后,發給相應的服務器端頁面(也就是腳本)來執行,腳本產生客戶端的響應,發送回客戶端3、 客戶…
- Qt的pdf查看器 使用Qt的WebEngine和javascript的pdf.js模塊構建的PDF查看器。這個基于qmake的項目定義了兩個構建目標:qpdf共享庫(ppdflib)和pdfviewer基于qpdf庫的示例PDF查看器。如何編譯僅支持Qt 5.9.x或更高版本;qpdf.pro在QtCreator中打開項目文件;構建并運行。如何使…