ASP.NET Core 6框架揭秘实例演示[37]:重定向的N种实现方式

这篇具有很好参考价值的文章主要介绍了ASP.NET Core 6框架揭秘实例演示[37]:重定向的N种实现方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在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”路径下。

ASP.NET Core 6框架揭秘实例演示[37]:重定向的N种实现方式

图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重写)规则,原始请求路径的正则表达式和重定向路径均保持不变。

using Microsoft.AspNetCore.Rewrite;

var app = WebApplication.Create();
var options = new RewriteOptions().
    .AddRewrite(regex: "^foo/(.*)", replacement: "bar/$1", skipRemainingRules: true);
app.UseRewriter(options);
app.MapGet("/{**foobar}", (HttpRequest request) =>
    $"{request.Scheme}://{request.Host}{request.PathBase}{request.Path}");
app.Run();
改动的程序启动后,如果利用浏览器采用相同的路径(“/foo/abc/123”)对站点发起请求,我们会得到如图2所示的相同的响应内容。由于这次采用的是服务端重定向,整个过程只会涉及一次报文交换,所以浏览器的请求地址不会改变。

ASP.NET Core 6框架揭秘实例演示[37]:重定向的N种实现方式

图2 服务端重定向

[S2503]采用IIS重写规则实现重定向

重定向是绝大部分Web服务器(比如IIS、Apache和Nginx等)都会提供的功能,但是不同的服务器类型针对重定向规则具有不同的定义方式。IIS中的重定向被称为“URL重写”,具体的URL重写规则采用XML格式进行定义,RewriteMiddleware中间件对它提供了原生的支持。我们将URL重写规则以如下的方式定义在创建的rewrite.xml文件中,并将该文件保存在演示项目的根目录下。

<rewrite>
    <rules>
       <rule name="foo">
	    <match url="^foo/(.*)" />
	    <action type="Redirect" url="baz/{R:1}" />
	</rule>
	<rule name="bar">
	    <match url="^bar/(.*)" />
	    <action type="Rewrite" url="baz/{R:1}" />
	</rule>
    </rules>
</rewrite>

如上所示的XML文件定义了两条指向目标地址“baz/{R:1}”的规则,这里的占位符“{R:1}”和前面定义的“$1”一样,都表示针对初始请求路径进行正则匹配时得到的第一段捕获内容。两条规则用来匹配原始路径的正则表达式分别定义为“^foo/(.*)”和“^bar/(.*)”。它们采用的Action类型也不相同,前者为“Redirect”,表示客户端重定向;后者为“Rewrite”,表示服务端重定向。

为了将采用XML文件定义的IIS重定向规则应用到演示程序中,我们对演示程序如下的修改。如代码片段所示,在RewriteOptions对象被创建出来后,我们调用了它的AddIISUrlRewrite扩展方法添加了IIS URL重写规则,该方法的两个参数分别表示用来读取规则文件的IFileProvider对象和规则文件针对该对象的路径。由于规则文件存储与项目根目录下,这也是ASP.NET应用“内容根目录”所在的位置,所以我们可以使用内容根目录对应的IFileProvider对象。

using Microsoft.AspNetCore.Rewrite;

var app = WebApplication.Create();
var options = new RewriteOptions().AddIISUrlRewrite(fileProvider: app.Environment.ContentRootFileProvider, filePath: "rewrite.xml");
app.UseRewriter(options);
app.MapGet("/{**foobar}", (HttpRequest request) =>$"{request.Scheme}://{request.Host}{request.PathBase}{request.Path}");
app.Run();

改动的程序启动之后,我们针对添加的两条重定向规则发送了对应的请求,它们采用的请求路径分别为“/foo/abc/123”和“/bar/abc/123”。从图3所示的输出可以看出,这两个请求均被重定向到相同的目标路径“/baz/abc/123”。

ASP.NET Core 6框架揭秘实例演示[37]:重定向的N种实现方式

图3 IIS重定向规则

由于发送的两个请求分别采用客户端和服务端重定向方式导向新的地址,所以浏览器针对前者显示的是重定向后的地址,对于后者则显示原始的地址。整个过程涉及到的如下三次报文交互更能说明两种重定向方式的差异,从报文内容我们可以进一步看出第一次采用的是响应状态码为301的永久重定向。

GET http://localhost:5000/foo/abc/123 HTTP/1.1
Host: localhost:5000

HTTP/1.1 301 Moved Permanently
Content-Length: 0
Date: Wed, 22 Sep 2021 23:26:02 GMT
Server: Kestrel
Location: /baz/abc/123
GET http://localhost:5000/baz/abc/123 HTTP/1.1
Host: localhost:5000

HTTP/1.1 200 OK
Date: Wed, 22 Sep 2021 23:26:02 GMT
Server: Kestrel
Content-Length: 33

http://localhost:5000/baz/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 23:26:26 GMT
Server: Kestrel
Content-Length: 33

http://localhost:5000/baz/abc/123

[S2504]采用Apache重写规则实现重定向

上面我们演示了RewriteMiddleware中间件针对IIS重定向规则的支持,实际上该中间件还支持Apache的重定向模块mod_rewriter所采用的重定向规则定义形式,我们照例来做一个简单的演示。我们在项目根目录下添加了一个名为rewrite.config的配置文件,并在其中定义了如下两条重定向规则。

RewriteRule ^/foo/(.*) /baz/$1 [R=307]
RewriteRule ^/bar/(.*) - [F]

上面第一条规则利用R这个Flag将路径与正则表达式“^/foo/(.*)”相匹配的请求以重定向到新的路径“/baz/$1”,具体采用的是针对状态码307的临时客户端重定向。对于其路径与正则表达式“^/bar/(.*)”相匹配的请求,我们将它视为未经授权授权的请求,所以对应的规则采用F(Forbidden)这个Flag。为了让演示程序采用上述这个配置文件定义的Apache重定向规则,我们只需要按照如下的方式调用RewriteOptions 对象的AddApacheModRewrite扩展方法就可以了。

using Microsoft.AspNetCore.Rewrite;

var app = WebApplication.Create();
var options = new RewriteOptions().AddApacheModRewrite(fileProvider: app.Environment.ContentRootFileProvider, filePath: "rewrite.config");
app.UseRewriter(options);
app.MapGet("/{**foobar}", (HttpRequest request) =>$"{request.Scheme}://{request.Host}{request.PathBase}{request.Path}");
app.Run();

改动的程序启动之后,我们针对添加的两条重定向规则发送了对应的请求,它们采用的请求路径分别为“/foo/abc/123”和“/bar/abc/123”。从图4所示的输出可以看出,第一个请求均被重定向到相同的目标路径“/baz/abc/123”,第二个请求返回一个状态码为403的响应。

ASP.NET Core 6框架揭秘实例演示[37]:重定向的N种实现方式

图4Apache mod­_rewrite重定向规则

如下所示的是整个过程涉及到的三次报文交换。我们可以看出第一次请求得到的响应状态码正式我们在规则中显式设置的307。第二个请求由于被视为权限不足,服务端直接返回一个状态为“403 Forbidden”的响应。

GET http://localhost:5000/foo/abc/123 HTTP/1.1
Host: localhost:5000

HTTP/1.1 307 Temporary Redirect
Content-Length: 0
Date: Wed, 22 Sep 2021 23:56:26 GMT
Server: Kestrel
Location: /baz/abc/123
GET http://localhost:5000/baz/abc/123 HTTP/1.1
Host: localhost:5000

HTTP/1.1 200 OK
Date: Wed, 22 Sep 2021 23:56:26 GMT
Server: Kestrel
Content-Length: 33
GET http://localhost:5000/bar/abc/123 HTTP/1.1
Host: localhost:5000

HTTP/1.1 403 Forbidden
Content-Length: 0
Date: Wed, 22 Sep 2021 23:56:33 GMT
Server: Kestrel

[S2505]基于HTTPS终结点的重定向

将针对HTTP请求重定向到对应HTTPS终结点是一种常见的重定向场景。如下所示的演示针对路径“/foo”和“/bar”注册了两个终结点,它们均由注册的两个中间件构建的RequestDelegate委托作为处理器,其中一个就是调用UseRewriter扩展方法注册的RewriteMiddleware中间件,另一个中间件则是通过调用Run扩展方法注册的,后者依然将最终请求的URL作为响应的内容。

using Microsoft.AspNetCore.Rewrite;

var app = WebApplication.Create();
app.MapGet("/foo", CreateHandler(app, 302));
app.MapGet("/bar", CreateHandler(app, 307));
app.Run();

static RequestDelegate CreateHandler(IEndpointRouteBuilder endpoints, int statusCode)
{
    var app = endpoints.CreateApplicationBuilder();
    app
        .UseRewriter(new RewriteOptions().AddRedirectToHttps(statusCode, 5001))
        .Run(httpContext => {
            var request = httpContext.Request;
            var address =
            $"{request.Scheme}://{request.Host}{request.PathBase}{request.Path}";
            return httpContext.Response.WriteAsync(address);
        });
    return app.Build();
}

两个终结点的处理器通过本地方法CreateHandler创建出来的。该方法调用当前WebApplication对象的CreateApplicationBuilder方法创建了一个新的IApplicationBuilder对象,并调用后者的UseRewriter扩展方法注册了RewriteMiddleware中间件。我们为该中间件提供的HTTPS重定向规则是通过调用RewriteOptions对象的AddRedirectToHttps扩展方法定义的,该方法时指定了重定向响应采用的状态码(302和307)和HTTPS终结点采用的端口号。改动的程序启动之后,针对两个终结点的HTTP请求(“http://localhost:5000/foo”和“http://localhost:5000/bar”)均以图5所示的形式被重定向到了对应的HTTPS终结点。

ASP.NET Core 6框架揭秘实例演示[37]:重定向的N种实现方式

图5 HTTPS重定向

整个过程涉及到如下四次报文交换,我们可以看出我们通过调用AddRedirectToHttps扩展方法定义的规则采用的是客户端重定向。重定向响应采用了我们设置的状态码,分别是“302 Found”和“307 Temporary Redirect”。文章来源地址https://www.toymoban.com/news/detail-480725.html

GET http://localhost:5000/foo HTTP/1.1
Host: localhost:5000

HTTP/1.1 302 Found
Content-Length: 0
Date: Thu, 23 Sep 2021 12:10:51 GMT
Server: Kestrel
Location: https://localhost:5001/foo
GET https://localhost:5001/foo HTTP/1.1
Host: localhost:5001

HTTP/1.1 200 OK
Date: Thu, 23 Sep 2021 12:10:51 GMT
Server: Kestrel
Content-Length: 26

https://localhost:5001/foo
GET http://localhost:5000/bar HTTP/1.1
Host: localhost:5000

HTTP/1.1 307 Temporary Redirect
Content-Length: 0
Date: Thu, 23 Sep 2021 12:10:57 GMT
Server: Kestrel
Location: https://localhost:5001/bar
GET https://localhost:5001/bar HTTP/1.1
Host: localhost:5001

HTTP/1.1 200 OK
Date: Thu, 23 Sep 2021 12:10:57 GMT
Server: Kestrel
Content-Length: 26

https://localhost:5001/bar

到了这里,关于ASP.NET Core 6框架揭秘实例演示[37]:重定向的N种实现方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《深入浅出.NET框架设计与实现》笔记6.2——ASP.NET Core应用程序多种运行模式之二——IIS 服务承载

     ASP.NET Core应用程序可以在多种运行模式下运行,包括自宿主(Self-Hosting)、IIS服务承载、桌面应用程序、服务承载。 因此选择和时的模式很重要。 IIS 服务承载 将 ASP.NET Core 应用程序托管在 Internet Information Services (IIS) 中。 利用 IIS 提供的高级功能,如负载均衡、HTTPS 支持和

    2024年04月26日
    浏览(46)
  • asp.net core 框架搭建2-搭建MVC后台管理系统

    作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/131458964 asp.net core 框架搭建2-搭建MVC后台管理系统 ,本文章介绍asp.net core框架搭建,然后开发一个后台管理系统,将一步步带着大家,实现目标。所有操作过程将展现在本篇文章,下面咋们一起来实现它吧。 使

    2024年02月12日
    浏览(62)
  • 【ASP.NET Core 基础知识】--MVC框架--Models和数据绑定

    Models和数据绑定在ASP.NET Core MVC中扮演着关键的角色,对于构建强大、灵活和可维护的Web应用程序至关重要。这一节我们就来讲一下。 一、Models 1.1 Models的定义和作用 在ASP.NET Core MVC中,Model是应用程序中用于表示数据结构和业务逻辑的一种抽象。Models充当了MVC(Model-View-Contr

    2024年01月23日
    浏览(52)
  • dotnet 简单方法在一个进程内同时跑起 WPF 和 ASP.NET Core 框架

    从设计架构上,无论是 WPF 还是 ASP.NET Core 框架,都是在 dotnet 运行时上层的应用,两个框架处于平级的结构。理论上讲,两个平级的框架只要不存在特殊的情况,都是能够相容存在的。本文将和大家介绍一个非常简单的方法,在一个进程内同时跑起 WPF 和 ASP.NET Core 框架 在一

    2024年04月26日
    浏览(45)
  • asp.net core框架搭建1-搭建webapi,对数据增删改查接口模板(附源码)

    作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/131458922 asp.net core 框架搭建2-搭建webapi ,本文章介绍asp.net core webapi框架搭建,然后开发增删改查和工具接口,将一步步带着大家,实现目标。所有操作过程将展现在本篇文章,下面咋们一起来实现它吧。 asp.ne

    2024年02月13日
    浏览(46)
  • 如何在ASP.NET Core应用中实现与第三方IoC/DI框架的整合?

    我们知道整个ASP.NET Core建立在以ServiceCollection/ServiceProvider为核心的DI框架上,它甚至提供了扩展点使我们可以与第三方DI框架进行整合。对此比较了解的读者朋友应该很清楚,针对第三方DI框架的整合可以通过在定义Startup类型的ConfigureServices方法返回一个ServiceProvider来实现。但

    2024年02月09日
    浏览(50)
  • ASP.NET Core + Jenkins实现自动化发布

    🏆作者:科技、互联网行业优质创作者 🏆专注领域:.Net技术、软件架构、人工智能、数字化转型、DeveloperSharp、微服务、工业互联网、智能制造 🏆欢迎关注我(Net数字智慧化基地),里面有很多 高价值 技术文章, 是你刻苦努力也积累不到的经验 ,能助你快速成长。升职

    2024年02月22日
    浏览(45)
  • 关于ASP.NET Core WebSocket实现集群的思考

    前言     提到 WebSocket 相信大家都听说过,它的初衷是为了解决客户端浏览器与服务端进行双向通信,是在单个 TCP 连接上进行全双工通讯的协议。在没有WebSocket之前只能通过浏览器到服务端的请求应答模式比如轮询,来实现服务端的变更响应到客户端,现在服务端也可以主

    2024年04月14日
    浏览(47)
  • ASP.NET Core+Vue3 实现SignalR通讯

    从ASP.NET Core 3.0版本开始,SignalR的Hub已经集成到了ASP.NET Core框架中。因此,在更高版本的ASP.NET Core中,不再需要单独引用Microsoft.AspNetCore.SignalR包来使用Hub。 在项目创建一个类继承Hub, 首先是写一个CreateConnection方法 ConnectionId是SignalR中标识的客户端连接的唯一标识符, 将userId和

    2024年02月06日
    浏览(42)
  • 2步轻松实现ASP.NET Core托管服务执行定时任务

    最近接到一个新项目,需要在项目里添加一个后台任务,定时去发邮件通知客户;由于是一个比较小型的项目,不希望引入Quartz.Net、Hangfire等太重的框架,同时也没持久化要;寻觅了一下发现ASP.NET Core本身带有托管服务,可以执行定时任务。ASP.NET Core提供了IHostedService接口,

    2024年02月06日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包