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发送一个新请求获取资源。

640?wx_fmt=png  将请求重定向到其他URL时,可以指定重定向是永久还是临时。301(Moved Permanently)状态代码用于表明资源具有新的永久URL,并且希望客户端将来对该资源的所有请求都应使用新URL。当收到301状态码时客户端可以缓存响应。302(Found)状态码用于临时重定向,所以客户端不应该存储和重用该URL。状态码的含义请参考这里。URL重写是服务器端操作,用于从不同的资源地址提供资源。URL重写不需要额外的往返服务器,并且重写后的URL不会返回给客户端,也不会出现在客户端的地址栏中。当/resource被重写为/different-resource时:客户端请求/resource,服务端在内部从/different-resource获取资源并响应给客户端。尽管客户端也许可以从重写后的URL处获取资源,但客户端并不会收到资源存在于重写后URL的通知。

640?wx_fmt=png

何时使用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重写选项传递到请求管道,以下是几种重写、重定向的配置代码,后面会针对每种配置单独解释:

640?wx_fmt=png

URL重定向

  使用AddRedirect方法重定向请求,第一个参数为匹配请求URL的正则表达式,第二个参数为替换的文本,第三个参数(如果存在)指定状态码,如果未指定状态码,默认为302(Found)。

640?wx_fmt=png

  打开浏览器的开发者工具,向/redirect-rule/1234/5678发送一个请求。重定向规则中的正则表达式将匹配请求路径,将路径替换为/redirected/1234/5678,服务端将重定向URL和302(Found)状态代码发送回客户端。客户端基于该URL发送新请求并将该URL显示到地址栏中,然后客户端收到一个200(OK)的响应。

警告:新建重定向规则时一定要谨慎,重定向规则将会对应用每一个请求都进行匹配,包括重定向后的URL。所以很容易不小心创建一个无限重定向循环。

   发送一个请求:/redirect-rule/1234/5678,响应如下图:

640?wx_fmt=png

 

  重定向规则中正则表达式括号内的部分称为捕获组,表达式中点(.)的含义是匹配任何字符,星号(*)表示匹配之前的字符零次或者多次。因此,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:

640?wx_fmt=png

   也可以使用AddRedirectToHttpsPermanent方法将不安全的请求重定向到具有安全HTTPS协议的同一主机和路径(端口443上的https://)。中间件将响应状态码设置为301(Moved Permanently)。

640?wx_fmt=png

注意:在不需要其他重定向规则的情况下重定向到HTTPS时,建议使用HTTPS重定向中间件。请参考这里

 URL重写

  可使用AddRewrite方法创建重写规则,第一个参数为匹配请求URL的正则表达式,第二个参数是替换字符串,第三个参数skipRemainingRules: {true|false},表示如果当前规则生效是否要跳过其它的重写规则。 

640?wx_fmt=png

  发送一个请求:/rewrite-rule/1234/5678,重定向请求及响应如下图:

640?wx_fmt=png

 

   我们注意到正则表达式开头是字符^,它的含义是匹配需要从URL路径的开头开始。在之前重定向例子中,正则表达式的开头并没有字符^,因此,路径中redirect-rule/之前的任何字符都可以成功匹配。

路径是否匹配
/redirect-rule/1234/5678
/my-cool-redirect-rule/1234/5678是 
/anotherredirect-rule/1234/5678

  在重写规则中,正则表达式^rewrite-rule/(\d+)/(\d+)仅匹配以rewrite-rule/开头的路径,请注意二者之间的区别:

路径是否匹配
/rewrite-rule/1234/5678
/my-cool-rewrite-rule/1234/5678
/anotherrewrite-rule/1234/5678

   在正则表达式^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规则

   使用AddApacheModRewrite方法应用Apache mod_rewrite规则,请确保规则文件已随应用程序部署至服务器。了解更多关于Apache mod_rewrite规则,请参考这里

640?wx_fmt=png

以下为ApacheModRewrite.txt的内容:

# Rewrite path with additional sub directory
RewriteRule ^/apache-mod-rules-redirect/(.*) /redirected?id=$1 [L,R=302]

示例应用程序将来自/apache-mod-rules-redirect/(.\*)的请求重定向到/redirected?id=$1,响应码为302(Found)。

中间件支持以下Apache mod_rewrite服务器变量:

  • CONN_REMOTE_ADDR

  • HTTP_ACCEPT

  • HTTP_CONNECTION

  • HTTP_COOKIE

  • HTTP_FORWARDED

  • HTTP_HOST

  • HTTP_REFERER

  • HTTP_USER_AGENT

  • HTTPS

  • IPV6

  • QUERY_STRING

  • REMOTE_ADDR

  • REMOTE_PORT

  • REQUEST_FILENAME

  • REQUEST_METHOD

  • REQUEST_SCHEME

  • REQUEST_URI

  • SCRIPT_FILENAME

  • SERVER_ADDR

  • SERVER_PORT

  • SERVER_PROTOCOL

  • TIME

  • TIME_DAY

  • TIME_HOUR

  • TIME_MIN

  • TIME_MON

  • TIME_SEC

  • TIME_WDAY

  • TIME_YEAR

使用IIS URL重写模块规则

  使用AddIISUrlRewrite方法应用IIS URL重写规则,请确保规则文件已随应用程序部署至服务器。在Windows Server IIS上运行时,不要让中间件直接使用web.config文件,规格文件应该存储于web.config之外,以避免和IIS重写模块冲突。了解更多关于IIS重写模块的规则,请参考这里和这里。

640?wx_fmt=png

以下为IISUrlRewrite.xml的内容:

640?wx_fmt=png

示例应用程序将来自/iis-rules-rewrite/(.*)的请求重写为/rewritten?id=$1,响应码为200(OK)。

ASP.NET Core 2.x发布的中间件不支持以下IIS URL重写模块功能:

  • Outbound Rules

  • Custom Server Variables

  • Wildcards

  • LogRewrittenUrl

中间件支持以下IIS URL重写模块服务器变量:

  • CONTENT_LENGTH

  • CONTENT_TYPE

  • HTTP_ACCEPT

  • HTTP_CONNECTION

  • HTTP_COOKIE

  • HTTP_HOST

  • HTTP_REFERER

  • HTTP_URL

  • HTTP_USER_AGENT

  • HTTPS

  • LOCAL_ADDR

  • QUERY_STRING

  • REMOTE_ADDR

  • REMOTE_PORT

  • REQUEST_FILENAME

  • REQUEST_URI

注意:可以通过PhysicalFileProvider类获取IFileProvider。这种方法可以为重写规则文件的位置提供更大的灵活性。

PhysicalFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());

基于方法的规则

  使用Add(Action<RewriteContext> applyRule)在方法中实现自己的规则逻辑,RewriteContext公开HttpContext以方便在方法中使用,而context.Result决定了如何进行后续的管道处理。如下表:

context.Result行为
RuleResult.ContinueRules(默认行为)继续应用后续规则
RuleResult.EndResponse停止应用规则并发送响应
RuleResult.SkipRemainingRules停止应用规则并发送上下文(HttpContext)至下个中间件

640?wx_fmt=png

  示例应用程序演示了将.xml结尾的请求路径重定向的自定义逻辑方法。如果对/file.xml发出请求,则会将其重定向到/xmlfiles/file.xml。响应码被设置为301 (Moved Permanently)。对于重定向来说,你必须显式指定响应的状态码,否则响应码将被默认为200(OK)且客户端也不会发生重定向。

   发送一个请求:/file.xml,响应如下图:

640?wx_fmt=png

基于IRule接口的规则

  使用Add(IRule)在从IRule派生的类中实现您自己的规则逻辑。使用IRule的方式比使用基于方法的规则方法具有更好的灵活性,派生类可以包含构造函数,您可以在其中传递ApplyRule方法的参数。

640?wx_fmt=png

640?wx_fmt=png

 发送一个请求:/image.png,响应内容如下:

640?wx_fmt=png

尾语

  本来主要内容来自于微软官方英文文档,点击这里查看原文,在翻译过程中,对有些句式和词汇进行了加工,以期望更加流畅和符合我们的阅读习惯,其中应该有不少不得体的地方,还请各位大神见谅并指出,如有一丝帮助,万分荣幸。

原文地址:https://www.cnblogs.com/luohelc/p/url_rewrite.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/320721.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

打击犯罪【并查集】

打击犯罪 题目大意&#xff1a; 有n个人&#xff0c;相互之间有一些关系&#xff0c;从而形成一个图&#xff0c;现在要从1……n1……n1……n按顺序去掉k个人&#xff08;即去掉1……k1……k1……k&#xff09;&#xff0c;使最大的子图的点数 <n/2<n/2<n/2&#xf…

StackExchange.Redis性能调优

编者&#xff1a;.net core redis 驱动推荐&#xff0c;为什么不使用 StackExchange.Redis 引起了很大的反响&#xff0c;大家反应过度&#xff0c;其实StackExchange.Redis 2.0已经从重构了异步队列&#xff0c;使用管道方式解决异步慢的问题。这篇文章也可以帮助大家正确认识…

糊涂的教授【拓扑排序】

糊涂的教授 题目大意&#xff1a; 有n个矩阵&#xff08;有些部分重叠在一起&#xff09;&#xff0c;现在有一些位置写着一些数字&#xff0c;表示它原来的序号&#xff0c;问每一个矩阵原来的序号 原题&#xff1a; 题目描述 陈教授是一个国际知名的教授&#xff0c;很多…

P6860-象棋与马【欧拉函数,杜教筛】

出题人来报个到 正题 题目链接:https://www.luogu.com.cn/problem/P6860 题目大意 p(a,b)1p(a,b)1p(a,b)1当且经当一只走a∗ba*ba∗b矩形的马可以走到棋盘上任何一个点 求∑a1n∑b1np(a,b)\sum_{a1}^n\sum_{b1}^np(a,b)a1∑n​b1∑n​p(a,b) 解题思路 这个马能走到全图的充要…

Codeforces Round #498 (Div. 3)

D. Two Strings Swaps 容易发现&#xff0c;a[i], a[n-i1], b[i], b[n-i1] 可以互相交换&#xff0c;且不会受其他地方影响&#xff0c;关键在于对于这4个字符怎们计算最小的操作数&#xff0c;讨论到死。。。看了别人的代码&#xff0c;用不同的字符对数表示字符的组成&#x…

用HttpClientFactory来实现简单的熔断降级

前言在2.1之后&#xff0c;有不少新东西&#xff0c;其中HttpClientFactory算是一个。HttpClientFactory涉及的东西也不算少&#xff0c;三四种clients , 请求中间件&#xff0c;与Polly的结合&#xff0c;生命周期等。Steeltoe的组件升级到2.1后&#xff0c;不少示例代码已经使…

【前缀和】【DP】登机(jzoj 5535)

登机 jzoj 5535 题目大意&#xff1a; 有一架飞机&#xff0c;有n个人要登机&#xff0c;每个人的不满值为登机时当前机舱在他所在行前方的人数总和&#xff0c;现在可以把飞机分为k个机舱&#xff0c;使不满值总和最小 原题&#xff1a; 题目描述 小H是机场登机的执行经…

后缀数组学习笔记

后缀数组学习笔记 说在前边 学习了《后缀数组——处理字符串的有力工具》终于感觉入门了&#xff0c;就总结一下&#xff0c;主要是应用原理讲解学习了 大佬Blog一些性质 height数组&#xff1a;定义height[i]suffix(sa[i-1])和suffix(sa[i])的最长公共前缀&#xff0c;也就是排…

CF140C-New Year Snowmen【优先队列】

正题 题目链接:https://www.luogu.com.cn/problem/CF140C 题目大意 nnn个雪球&#xff0c;一个雪人需要用333个不同大小的雪球堆起&#xff0c;求最多雪人。 解题思路 我们每次拿相同雪球中最多的三个来堆即可&#xff0c;用优先队列维护。 时间复杂度O(nlog⁡n)O(n\log n)O…

基于.net standard 的动态编译实现

在前文[基于.net core 微服务的另类实现]结尾处&#xff0c;提到了如何方便自动的生成微服务的客户端代理&#xff0c;使对于调用方透明&#xff0c;同时将枯燥的东西使用框架集成&#xff0c;以提高使用便捷性。在尝试了基于 Emit 中间语言后&#xff0c;最终决定使用生成代码…

线段树动态开点区间加区间求和

线段树动态开点区间加区间求和 题目来源&#xff1a; 陕西师范大学第七届程序设计竞赛网络同步赛 H. 万恶的柯怡 思想&#xff1a; 保证叶子节点被完整的覆盖&#xff0c;需要开节点&#xff0c;就把左右儿子都开出来&#xff0c;其余和普通线段树一样。 tips&#xff1a; 用结…

初一模拟赛总结(6.6 my brother高考前一天,加油!(。・`ω´・。))

成绩&#xff1a; 注&#xff1a;rankrankrank是有算其他$dalao的 T1T1T1好像因为精度问题被卡了 rankrankranknamenamenamescorescorescoreT1T1T1T2T2T2T3T3T3T4T4T4111hkyhkyhky180180180100100100000808080000222whdwhdwhd130130130100100100000202020101010222lyflyflyf13…

P1337-[JSOI2004]平衡点/吊打XXX【模拟退火】

正题 题目链接:https://www.luogu.com.cn/problem/P1337 题目大意 nnn个点有重量wiw_iwi​&#xff0c;求重心。 解题思路 模拟退火随机找一个重心然后不断接近即可。 codecodecode #include<cstdio> #include<cstring> #include<algorithm> #include<…

基于阿里云 DNS API 实现的 DDNS 工具

0.简要介绍0.1 思路说明AliDDNSNet 是基于 .NET Core 开发的动态 DNS 解析工具&#xff0c;借助于阿里云的 DNS API 来实现域名与动态 IP 的绑定功能。工具核心就是调用了阿里云 DNS 的两个 API &#xff0c;一个 API 获取指定域名的所有解析记录&#xff0c;然后通过比对与当前…

【拓扑排序】【DP】奖金(ssl 1325)

奖金 ssl 1325 题目大意&#xff1a; 有n个人&#xff0c;某个人要比另外一个人的工资高&#xff08;工资最低为100&#xff0c;最少多1元&#xff09;&#xff0c;问最少发多少工资 原题&#xff1a; 题目描述 由于无敌的凡凡在2005年世界英俊帅气男总决选中胜出&#x…

网络流24题

网络流24题 说在前边 一直没有完整的刷过这套题&#xff0c;打算最近一点点刷掉通过《最小割模型在信息学竞赛中的应用》及《浅析一类最小割问题》学习常规建图技巧飞行员配对方案问题 二分图最大匹配 #include <bits/stdc.h> typedef long long ll; const int inf 0x3f…

P3959-宝藏【模拟退火】

正题 题目链接:https://www.luogu.com.cn/problem/P3959 题目大意 nnn个点&#xff0c;mmm条边&#xff0c;求一棵有根生成树权值最小。对于一条边(fa,x,w)(fa,x,w)(fa,x,w)会产生权值depfa∗wdep_{fa}*wdepfa​∗w。 解题思路 我们模拟退火每次随机一个序列&#xff0c;然后…

ASP.NET Core Web API 集成测试中使用 Bearer Token

在 ASP.NET Core Web API 集成测试一文中, 我介绍了ASP.NET Core Web API的集成测试. 在那里我使用了测试专用的Startup类, 里面的配置和开发时有一些区别, 例如里面去掉了用户身份验证相关的中间件.但是有些被测试的行为里面需要用到身份/授权信息.所以本文就介绍一下在API集成…

桐桐的雷达

桐桐的雷达 题目大意&#xff1a; 有一堆数字&#xff0c;并给出一个范围&#xff0c;判断不在范围内的数字是否多过10%&#xff0c;若不多过&#xff0c;那输出范围内数字的平均值 原题&#xff1a; 题目描述 桐桐在去广州的路上&#xff0c;对高速公路上的测速雷达产生了…

Codeforces Round #497 (Div. 1)

Codeforces Round #497 (Div. 1) A. Reorder the Array 先满足数值较小的位置&#xff0c;每次找恰好大于这个值的一个值即可。 #include <bits/stdc.h> #define rep(i,a,b) for(int ia;i<b;i) #define pb push_back typedef long long ll; const int N 100200; usin…