可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
On an ASP.Net Core application startup I have:
RewriteOptions rewriteOptions = new RewriteOptions();
rewriteOptions.AddRedirectToHttps();
applicationBuilder.UseRewriter(rewriteOptions);
When in Production I need to redirect all Non WWW to WWW Urls
For example:
domain.com/about > www.domain.com/about
How can I do this using Rewrite Middleware?
I think this can be done using AddRedirect and Regex:
Github - ASP.NET Core Redirect Docs
But not sure how to do it ...
回答1:
A reusable alternative would be to create a custom rewrite rule and a corresponsing extension method to add the rule to the rewrite options. This would be very similar to how AddRedirectToHttps works.
Custom Rule:
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;
}
}
Extension Method:
public static class RewriteOptionsExtensions
{
public static RewriteOptions AddRedirectToWww(this RewriteOptions options)
{
options.Rules.Add(new RedirectToWwwRule());
return options;
}
}
Usage:
var options = new RewriteOptions();
options.AddRedirectToWww();
options.AddRedirectToHttps();
app.UseRewriter(options);
Future versions of the rewrite middleware will contain the rule and the corresponding extension method. See this pull request
回答2:
I'm more of an Apache user and fortunately URL Rewriting Middleware in ASP.NET Core provides a method called AddApacheModRewrite
to perform mod_rewrite
rules on the fly.
1- Create a .txt
file whatever the name and put these two lines into it:
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
2- then call it this way:
AddApacheModRewrite(env.ContentRootFileProvider, "Rules.txt")
Done!
回答3:
Using just a regex,
Find ^(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,})))
Replace $1www.$2
Expanded
^ # 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)
回答4:
It's unclear from if what AddRedirect method does and if it actually accepts regex.
But to insert a "www" to a url without "www"?
You could try it with these strings:
string pattern = @"^(https?://)(?!www[.])(.*)$";
string replacement = "$1www.$2";
//Regex rgx = new Regex(pattern);
//string redirectUrl = rgx.Replace(url, replacement);
Because of the negative lookahead (?!www[.])
after the protocol, it'll ignore strings like http://www.what.ever
$1 and $2 are the first and second capture groups.
回答5:
I think instead of using Regex unless it is a must you can use the Uri class to reconstruct your url
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}";
And the result will look like
Output: http://www.example.com/test/page.html?query=new&sortOrder=ASC
回答6:
Here's a regex to try:
(http)(s)?(:\/\/)[^www.][A-z0-9]+(.com|.gov|.org)
It will select URLs like:
http://example.com
https://example.com
http://example.gov
https://example.gov
http://example.org
https://example.org
But not like:
http://www.example.com
https://www.example.com
I prefer to use explicit extensions (e.g. .com
, .gov
, or .org
) when possible, but you could also use something like this if it is beneficial to your use case:
(http)(s)?(:\/\/)[^www.][A-z0-9]+(.*){3}
I would then approach the replacement with something like the following:
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."));
}
回答7:
You don't need a RegEx, just a simple replace will work:
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."));
}