c# - URL 重写中间件 ASP.Net Core 2.0
问题描述
我无法正确编写 URL 重写中间件。我认为正则表达式是正确的。我第一次使用这个功能,也许我不明白。
示例网址:
http://localhost:55830/shop/alefajniealsdnoqwwdnanxc!@#lxncqihen41j2ln4nkzcbjnzxncas?valueId=116
http://localhost:55830/shop/whatever?valueId=116
http://localhost:55830/shop/toquestionmark?valueId=116
正则表达式:
\/shop\/([^\/?]*)(?=[^\/]*$)
启动,配置:
var rewrite = new RewriteOptions().AddRewrite(
@"\/shop\/([^\/?]*)(?=[^\/]*$)",
"/shop/$1",
true
);
app.UseRewriter(rewrite);
也许与其他方法相关的顺序有问题?
控制器:
[Route(RouteUrl.Listing + RouteUrl.Slash + "{" + ActionFilter.Value + "?}", Name = RouteUrl.Name.ShopBase)]
public ActionResult Index(string value, int valueId)
{
return View();
}
例如,当我重定向到:
我想显示这样的网址:
解决方案
基于这篇文章: https ://www.softfluent.com/blog/dev/Page-redirection-and-URL-Rewriting-with-ASP-NET-Core
在开发 Web 应用程序时,经常需要添加一些重定向规则。最常见的重定向规则是:从“http”重定向到“https”、添加“www”或将网站移动到另一个域。URL 重写通常用于提供用户友好的 URL。
我想解释重定向和重写之间的区别。重定向向客户端发送 HTTP 301 或 302,告诉客户端它应该使用另一个 URL 访问页面。浏览器将更新地址栏中可见的 URL,并使用新 URL 发出新请求。另一方面,重写发生在服务器上,是将一个 URL 转换为另一个 URL。服务器将使用新的 URL 来处理请求。客户端不知道服务器已经重写了 URL。
使用 IIS,您可以使用该web.config
文件来定义重定向和重写规则或使用RewritePath
:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect to https">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="Off" />
<add input="{REQUEST_METHOD}" pattern="^get$|^head$" />
<add input="{HTTP_HOST}" negate="true" pattern="localhost" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
但是,这不再适用于 ASP.NET Core。相反,您可以使用新的 NuGet 包:Microsoft.AspNetCore.Rewrite (GitHub)。该软件包非常易于使用。打开 startup.cs 文件并编辑 Configure 方法:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ISiteProvider siteProvider)
{
app.UseRewriter(new RewriteOptions()
.AddRedirectToHttps()
.AddRedirect(@"^section1/(.*)", "new/$1", (int)HttpStatusCode.Redirect)
.AddRedirect(@"^section2/(\\d+)/(.*)", "new/$1/$2", (int)HttpStatusCode.MovedPermanently)
.AddRewrite("^feed$", "/?format=rss", skipRemainingRules: false));
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
这些规则基于正则表达式和替换。正则表达式在 HttpContext.Request.Path 上进行评估,它不包括域,也不包括协议。这意味着您无法使用此方法重定向到另一个域或添加“www”,但别担心,我会告诉你如何做到这一点!
Microsoft 已决定帮助您使用此新软件包。事实上,如果你已经有一个 web.config 文件甚至一个 .htaccess 文件(.net core 是跨平台的)你可以直接导入它们:
app.UseRewriter(new RewriteOptions()
.AddIISUrlRewrite(env.ContentRootFileProvider, "web.config")
.AddApacheModRewrite(env.ContentRootFileProvider, ".htaccess"));
如果您有无法使用正则表达式表达的复杂规则,您可以编写自己的规则。规则是实现 Microsoft.AspNetCore.Rewrite.IRule 的类:
// app.UseRewriter(new RewriteOptions().Add(new RedirectWwwRule()));
public class RedirectWwwRule : Microsoft.AspNetCore.Rewrite.IRule
{
public int StatusCode { get; } = (int)HttpStatusCode.MovedPermanently;
public bool ExcludeLocalhost { get; set; } = true;
public void ApplyRule(RewriteContext context)
{
var request = context.HttpContext.Request;
var host = request.Host;
if (host.Host.StartsWith("www", StringComparison.OrdinalIgnoreCase))
{
context.Result = RuleResult.ContinueRules;
return;
}
if (ExcludeLocalhost && string.Equals(host.Host, "localhost", StringComparison.OrdinalIgnoreCase))
{
context.Result = RuleResult.ContinueRules;
return;
}
string newPath = request.Scheme + "://www." + host.Value + request.PathBase + request.Path + request.QueryString;
var response = context.HttpContext.Response;
response.StatusCode = StatusCode;
response.Headers[HeaderNames.Location] = newPath;
context.Result = RuleResult.EndResponse; // Do not continue processing the request
}
}
推荐阅读
- aws-lambda - 无服务器架构中的 Http 标头
- linux - 执行带有 docker | 的 shell 脚本 找不到 docker 命令
- android - 有没有办法从 Android 开发者设置中读取“选择模拟位置应用程序”?
- html - Bootstrap 4.3 - 如何定位具有绝对位置但在右侧和特定高度的图像
- python - 如何减去字典中的值
- javascript - 基于 Django 中的事件的动态内容着色变化
- python - 如何在 MongoDB 中加入多个集合(一对多关系)?
- javascript - 在没有 NodeJS 的情况下编写 Javascript 测试
- r - 如何为一组图添加一个常见的 y 和 x 标签,以及在 R 中为该排列的几列添加一个标签?
- python - 使用 BeautifulSoup 解析获取的 html 内容