Применение правил Apache для URL Rewriting

Последнее обновление: 09.05.2022

Для написания правил для URL Rewriting мы также можем использовать стандартные правила для веб-сервера Apache, которые обычно помещаются в файл htaccess. Что может быть особенно полезно, если сайт ранее был написан на PHP, а потом его решили перенести на ASP.NET Core. Однако надо заметить, что вряд ли получится взять все правила из htaccess и простым копированием перенести в проект для ASP.NET Core, поскольку не все они могут работать или работать так, как на Apache. И в случае с каждым правилом лучше, конечно же, тестировать.

Итак, добавим в корень проекта ASP.NET Core новый текстовый файл, который назовем rewrite.txt. Определим в этом файле следующее содержимое:

# удаление концевого слеша
RewriteRule (.*)/$ $1 [R=301]
# переадресация  home/index на /
RewriteRule "Home/Index$" "/" [NC,R=301]
# подмена адреса типа Home/Products/2/phones на Home/Products?id=2&name=phones
RewriteRule Home/Products/([0-9]+)/([0-9a-z-]+) Home/Products?id=$1&name=$2 [NC]

Для переопределения адресов применяется слово RewriteRule, которое в качестве параметра принимает выражение, которому должен соответствовать адрес, и ссылку, на которую будет осуществлен переход.

Первое выражение RewriteRule получает запрошенный путь, сравнивает его с регулярным выражением, и если сравнение прошло успешно, то преобразует адрес. Последующим RewriteRule передается результат предыдущих преобразований.

Регулярные выражения могут иметь группы, ограниченные круглыми скобками. В преобразованном адресе на каждую группу мы можем ссылаться через выражения типа $1, где число 1 - это порядковый номер группы. Например, в регулярном выражении "(.*)/$" $1 передает ту часть пути, которая идет до конечного слеша.

В выражении "Home/Products/([0-9]+)/([0-9a-z-]+)" уже две группы, для обращения к которым можно использовать токены $1 и $2 соответственно.

Если надо выполнить переадресацию, то в конце правила используется выражение [R=301] или [R]. В случае с третьим правилом никакой переадресации нет, будет просто подмена одного адреса на другой.

Кроме того, поскольку при определении правил Apache по умолчанию учитывается регистр (то есть Home и home - это не одно и то же), то чтобы регистр не учитывался, также используется флаг [NC].

Более подробно про правила URL Rewriting, которые применяются в Apache, можно посмотреть в официальной документации.

Для использования этого файла применяется метод AddApacheModRewrite():

using Microsoft.AspNetCore.Rewrite; // Пакет с middleware URL Rewriting

var builder = WebApplication.CreateBuilder();

var app = builder.Build();

IHostEnvironment? env = app.Services.GetService<IHostEnvironment>();
if(env is not null)
{
    var options = new RewriteOptions()
                    .AddApacheModRewrite(env.ContentRootFileProvider, "rewrite.txt");
    app.UseRewriter(options);
}

app.MapGet("/", async context => await context.Response.WriteAsync("Hello World!"));
app.MapGet("/home/products", async context =>
    await context.Response.WriteAsync($"Values:  id = {context.Request.Query["id"]} name = {context.Request.Query["name"]}"));

app.Run();

В метод AddApacheModRewrite передается провайдер файлов, который позволит сформировать путь к файлу правил и также название самого файла. В данном случае провайдер получаем через свойствам env.ContentRootFileProvider встроенного сервиса IHostEnvironment.

В качестве альтернативы можно использовать другой способ получения конфигурации Apache из файла:

using System.IO;

using (StreamReader apacheReader = File.OpenText("rewrite.txt"))
{
	var options = new RewriteOptions().AddApacheModRewrite(apacheReader);
	app.UseRewriter(options);
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850