Redirect Non WWW to WWW using Asp.Net Core Middleware

此生再无相见时 提交于 2019-11-28 02:45:40

问题


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."));
}


来源:https://stackoverflow.com/questions/43823413/redirect-non-www-to-www-using-asp-net-core-middleware

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!