ASP.NET Core 6中,如何实现多种重定向方法?
摘要:在HTTP的语义中,重定向一般指的是服务端通过返回一个状态码为3XX的响应促使客户端像另一个地址再次发起请求,本章将此称为“客户端重定向“。既然有客户端重定向,自然就有服务端重定向,本章所谓的服务端重定向指的是在服务端通过改变请求路径将请求
在HTTP的语义中,重定向一般指的是服务端通过返回一个状态码为3XX的响应促使客户端像另一个地址再次发起请求,本章将此称为“客户端重定向“。既然有客户端重定向,自然就有服务端重定向,本章所谓的服务端重定向指的是在服务端通过改变请求路径将请求导向另一个终结点。ASP.NET下的重定向是通过RewriteMiddleware中间件实现的。(本文提供的示例演示已经同步到《ASP.NET Core 6框架揭秘-实例演示版》)
[S2501]客户端重定向 (源代码)
[S2502]服务端重定向 (源代码)
[S2503]采用IIS重写规则实现重定向(源代码)
[S2504]采用Apache重写规则实现重定向(源代码)
[S2505]基于HTTPS终结点的重定向(源代码)
[S2501]客户端重定向我们可以为RewriteMiddleware中间件定义客户端重定向规则使之返回一个Location报头指向重定向地址的3XX响应。客户端(比如浏览器)在接收到这样的响应后会根据状态码约定的语义向重定向地址重新发起请求,我们将这种由客户端对新的地址重新请求的方式称为“客户端重定向”。
下面演示的这个例子会将请求路径以“foo/**”为前缀的请求重定向到新的路径“/bar/**”。如代码片段所示,我们通过调用UseRewriter扩展方法注册了RewriteMiddleware中间件,该方法会将对应的RewriteOptions配置选项作为参数。我们直接调用构造函数创建的这个RewriteOptions对象,并调用其AddRedirect扩展方法添加了一个重定向规则,该方法定义了两个参数,前者(“^/foo/(.*)”)代表参与重定向的原始路径模式(正则表达式),后者(“baz/$1”)表示重定向目标地址模板,占位符“$1”表示在进行正则匹配时产生的首段捕获内容(前缀“foo/”后面的部分)。请求的URL会作为响应的内容。
using Microsoft.AspNetCore.Rewrite;
var app = WebApplication.Create();
var options = new RewriteOptions().AddRedirect("^foo/(.*)", "bar/$1");
app.UseRewriter(options);
app.MapGet("/{**foobar}", (HttpRequest request) =>$"{request.Scheme}://{request.Host}{request.PathBase}{request.Path}");
app.Run();
演示程序注册了一个采用“/{**foobar}”路由模板的终结点,请求URL直接作为该终结点的响应内容。演示程序启动之后,所有路径以“/foo”为前缀的请求都会自动重定向到以“/bar”为前缀的地址。如果请求路径被设置为“/foo/abc/123”,最终将会被重定向到图1所示的“/bar/abc/123”路径下。
图1 客户端重定向
整个过程涉及HTTP报文交换更能体现客户端重定向的本质。如下所示的是整个过程涉及的两次报文交换,我们可以看出服务端第一次返回的是状态码为302的响应,根据映射规则生成的重定向地址体现在Location报头上。
GET http://localhost:5000/foo/abc/123 HTTP/1.1
Host: localhost:5000
HTTP/1.1 302 Found
Content-Length: 0
Date: Wed, 22 Sep 2021 13:34:17 GMT
Server: Kestrel
Location: /bar/abc/123
GET http://localhost:5000/bar/abc/123 HTTP/1.1
Host: localhost:5000
HTTP/1.1 200 OK
Date: Wed, 22 Sep 2021 13:34:17 GMT
Server: Kestrel
Content-Length: 33
http://localhost:5000/bar/abc/123
[S2502]服务端重定向服务端重定向会在服务端通过重写请求路径的方式将请求重定向到新的终结点。对于前面演示的程序来说,我们只需要对它做简单的修改就能切换到服务端重定向。如下面的代码片段所示,在RewriteOptions对象被创建后,我们调用它的另一个AddRewrite扩展方法注册了一条服务端重定向(URL重写)规则,原始请求路径的正则表达式和重定向路径均保持不变。
