Перенаправление вне WWW на WWW с использованием промежуточного ПО Asp.Net Core

При запуске приложения ASP.Net Core я:

RewriteOptions rewriteOptions = new RewriteOptions(); 

rewriteOptions.AddRedirectToHttps();

applicationBuilder.UseRewriter(rewriteOptions);

Когда в Production мне нужно перенаправить все Non WWW на WWW Urls

Например:

domain.com/about > www.domain.com/about

Как это сделать, используя промежуточное ПО Rewrite?

Я думаю, что это можно сделать с помощью AddRedirect и Regex:

Github - Документы по переадресации основного документа ASP.NET

Но не уверен, как это сделать...

Ответ 1

Используя только регулярное выражение,

Найти ^(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)

Ответ 2

Я больше пользователь Apache и, к счастью, URL-адрес Rewriting Middleware в ASP.NET Core предоставляет метод под названием 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

Альтернативой для повторного использования было бы создание настраиваемого правила перезаписи и метода расширения, чтобы добавить правило к параметрам перезаписи. Это будет очень похоже на работу 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);

Будущие версии промежуточного программного обеспечения перезаписи будут содержать правило и соответствующий метод расширения. См. этот запрос на растяжение

Ответ 4

Неясно, работает ли какой метод AddRedirect и действительно ли он принимает регулярное выражение.

Но вставить "www" в URL без "www"?
Вы можете попробовать это с помощью следующих строк:

string pattern = @"^(https?://)(?!www[.])(.*)$";
string replacement = "$1www.$2";

//Regex rgx = new Regex(pattern);
//string redirectUrl = rgx.Replace(url, replacement);

Из-за отрицательного lookahead (?!www[.]) после протокола он будет игнорировать строки, такие как http://www.what.ever

$1 и $2 - первая и вторая группы захвата.

Ответ 5

Я думаю, вместо использования Regex, если это не обязательно, вы можете использовать класс Uri для восстановления вашего 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}";

И результат будет выглядеть как

Output: http://www.example.com/test/page.html?query=new&sortOrder=ASC

Ответ 6

Вам не нужен 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."));
}

Ответ 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."));
}