使用 Asp.Net Core 中间件将非 WWW 重定向到 WWW
Posted
技术标签:
【中文标题】使用 Asp.Net Core 中间件将非 WWW 重定向到 WWW【英文标题】:Redirect Non WWW to WWW using Asp.Net Core Middleware 【发布时间】:2017-10-05 00:36:54 【问题描述】:在 ASP.Net Core 应用程序启动时,我有:
RewriteOptions rewriteOptions = new RewriteOptions();
rewriteOptions.AddRedirectToHttps();
applicationBuilder.UseRewriter(rewriteOptions);
在生产中,我需要将所有非 WWW 重定向到 WWW 网址
例如:
domain.com/about > www.domain.com/about
如何使用重写中间件做到这一点?
我认为这可以使用 AddRedirect 和 Regex 来完成:
Github - ASP.NET Core Redirect Docs
但不知道怎么做...
【问题讨论】:
AddApacheModRewrite
在这种情况下有效吗?
【参考方案1】:
可重用的替代方法是创建自定义重写规则和相应的扩展方法,以将规则添加到重写选项。这与 AddRedirectToHttps 的工作方式非常相似。
自定义规则:
public class RedirectToWwwRule : IRule
public virtual void ApplyRule(RewriteContext context)
var req = context.HttpContext.Request;
if (req.Host.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase))
context.Result = RuleResult.ContinueRules;
return;
if (req.Host.Value.StartsWith("www.", StringComparison.OrdinalIgnoreCase))
context.Result = RuleResult.ContinueRules;
return;
var wwwHost = new HostString($"www.req.Host.Value");
var newUrl = UriHelper.BuildAbsolute(req.Scheme, wwwHost, req.PathBase, req.Path, req.QueryString);
var response = context.HttpContext.Response;
response.StatusCode = 301;
response.Headers[HeaderNames.Location] = newUrl;
context.Result = RuleResult.EndResponse;
扩展方法:
public static class RewriteOptionsExtensions
public static RewriteOptions AddRedirectToWww(this RewriteOptions options)
options.Rules.Add(new RedirectToWwwRule());
return options;
用法:
var options = new RewriteOptions();
options.AddRedirectToWww();
options.AddRedirectToHttps();
app.UseRewriter(options);
重写中间件的未来版本将包含规则和相应的扩展方法。见this pull request
【讨论】:
如果您希望您的应用程序处理不同的子域,它是否打算仅使用 PR 从无子域重定向到 www?所以例如mydomain.org
转到 www.mydomain.org
,但 ww2.mydomain.org
保持不变?【参考方案2】:
我更像是一个 Apache 用户,幸运的是 ASP.NET Core 中的 URL 重写中间件提供了一个名为 AddApacheModRewrite
的方法来即时执行 mod_rewrite
规则。
1- 创建一个.txt
文件,无论名称如何,并将这两行放入其中:
RewriteCond %HTTP_HOST !^www\. [NC]
RewriteRule ^(.*)$ http://www.%HTTP_HOST/$1 [R=301,L]
2-然后这样称呼它:
AddApacheModRewrite(env.ContentRootFileProvider, "Rules.txt")
完成!
【讨论】:
【参考方案3】:只使用一个正则表达式,
找到^(https?://)?((?!www\.)(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]2,)))
替换$1www.$2
展开
^ # BOS
( # (1 start), optional http(s)
https? ://
)? # (1 end)
( # (2 start), domains without www prefix
(?! www\. )
(?:
(?: [a-z\u00a1-\uffff0-9]+ -? )*
[a-z\u00a1-\uffff0-9]+
)
(?:
\.
(?: [a-z\u00a1-\uffff0-9]+ -? )*
[a-z\u00a1-\uffff0-9]+
)*
(?:
\.
(?: [a-z\u00a1-\uffff]2, )
)
) # (2 end)
【讨论】:
这个正则表达式解决方案看起来不错,但与 ASP 重写中间件没有任何关系,并且 OP 在赏金之前有类似的基于正则表达式的解决方案。【参考方案4】:自 ASP.NET Core 3.0 (2019) 起,可以使用以下方法:
AddRedirectToWwwPermanent() AddRedirectToWww()示例
app.UseRewriter(new RewriteOptions()
.AddRedirectToWww());
见https://docs.microsoft.com/en-us/aspnet/core/fundamentals/url-rewriting?view=aspnetcore-5.0
【讨论】:
app.UseRewriter(new RewriteOptions().AddRedirectToWwwPermanent());对于永久重定向,请使用此。【参考方案5】:尚不清楚 AddRedirect 方法是否执行以及它是否真的接受正则表达式。
但是要在没有“www”的网址中插入“www”? 您可以使用以下字符串进行尝试:
string pattern = @"^(https?://)(?!www[.])(.*)$";
string replacement = "$1www.$2";
//Regex rgx = new Regex(pattern);
//string redirectUrl = rgx.Replace(url, replacement);
由于协议后面的负前瞻(?!www[.])
,它会忽略像http://www.what.ever这样的字符串
$1 和 $2 是第一个和第二个捕获组。
【讨论】:
看起来不错,但是如果您可以匹配和替换起始字符,为什么还要匹配整个 URL?string pattern = @"^https?://(?!www[.])";
和 string replacement = "$&www.";
@JohanWentholt 好吧,我想我当时不确定正则表达式引擎是否会使用 $& 或 $0 进行匹配。但你的版本是更好的高尔夫。看到这家伙现在对这么老的问题投入巨资,我有点惊讶。哦,没关系,他改变了问题。也许他应该刚刚开始一个新的......【参考方案6】:
我认为,除非必须,否则不要使用正则表达式,您可以使用 Uri 类来重构您的网址
var uri = new Uri("http://example.com/test/page.html?query=new&sortOrder=ASC");
var returnUri = $"uri.Scheme://www.uri.Authority
string.Join(string.Empty, uri.Segments)uri.Query";
结果会是这样的
Output: http://www.example.com/test/page.html?query=new&sortOrder=ASC
【讨论】:
我需要使用正则表达式,因为这是在 ASP.NET Core 方法中使用的。【参考方案7】:这是一个可以尝试的正则表达式:
(http)(s)?(:\/\/)[^www.][A-z0-9]+(.com|.gov|.org)
它将选择如下 URL:
http://example.com
https://example.com
http://example.gov
https://example.gov
http://example.org
https://example.org
但不喜欢:
http://www.example.com
https://www.example.com
如果可能,我更喜欢使用显式扩展(例如.com
、.gov
或.org
),但如果它对您的用例有益,您也可以使用类似的扩展:
(http)(s)?(:\/\/)[^www.][A-z0-9]+(.*)3
然后我会用类似以下的方式来处理替换:
Regex r = new Regex(@"(http)(s)?(:\/\/)[^www.][A-z0-9]+(.*)3");
string test = @"http://example.org";
if (r.IsMatch(test))
Console.WriteLine(test.Replace("https://", "https://www."));
Console.WriteLine(test.Replace("http://", "http://www."));
【讨论】:
正则表达式似乎不正确[^www.]
匹配 不是 w 或 的 单个 字符>.(点)。用http://willywonka.com
试试你的正则表达式。【参考方案8】:
您不需要 RegEx,只需简单的替换即可:
var temp = new string[] "http://google.com", "http://www.google.com", "http://gmail.com", "https://www.gmail.com", "https://example.com";
var urlWithoutWWW = temp.Where(d =>
d.IndexOf("http://www") == -1 && d.IndexOf("https://www") == -1);
foreach (var newurl in urlWithoutWWW)
Console.WriteLine(newurl.Replace("://", "://www."));
【讨论】:
我需要使用正则表达式,因为这是在 ASP.NET Core 方法中使用的。 所以,这个可以在.net core中使用。【参考方案9】:现在最常见的情况是,您希望同时重定向到 www 和 https。 hankors 的回答很好,但需要两个重定向而不是一个,所以我重写了他的自定义规则,以便在需要时添加 www 和 https。结果只是一个重定向(如果您在 Azure 中打开 https 重定向)。
public class RedirectToHttpsWwwRule : IRule
public void ApplyRule(RewriteContext context)
var req = context.HttpContext.Request;
if (req.Host.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase))
context.Result = RuleResult.ContinueRules;
return;
HostString wwwHost;
if (req.IsHttps)
if (req.Host.Value.StartsWith("www.", StringComparison.OrdinalIgnoreCase))
context.Result = RuleResult.ContinueRules;
return;
else
wwwHost = new HostString($"www.req.Host.Value");
else
if (req.Host.Value.StartsWith("www.", StringComparison.OrdinalIgnoreCase))
wwwHost = new HostString(req.Host.Value);
else
wwwHost = new HostString($"www.req.Host.Value");
string newUrl = UriHelper.BuildAbsolute("https", wwwHost, req.PathBase, req.Path, req.QueryString);
var response = context.HttpContext.Response;
response.StatusCode = 301;
response.Headers[HeaderNames.Location] = newUrl;
context.Result = RuleResult.EndResponse;
【讨论】:
【参考方案10】:我也在 .net 6 ASP.net 应用程序中使用了 SuperDuck 的答案。我的代码是:
using Microsoft.AspNetCore.Rewrite;
app.UseRewriter(new RewriteOptions().AddRedirectToWwwPermanent().AddRedirectToHttpsPermanent()); // in program.cs
它重定向到 www 子域以及 web-app 的 https 版本。
【讨论】:
这并不能真正回答问题。如果您有其他问题,可以点击 提问。要在此问题有新答案时收到通知,您可以follow this question。一旦你有足够的reputation,你也可以add a bounty 来引起对这个问题的更多关注。 - From Review以上是关于使用 Asp.Net Core 中间件将非 WWW 重定向到 WWW的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core 2.1 中的 HttpClientFactory (Part 3) 使用Handler实现传出请求中间件