ASP.NET Core'da URL Yeniden Yazma Ara Yazılımı

Tarafından Kirk Larkin ve Rick Anderson

Bu makalede, ASP.NET Core uygulamalarında URL Yeniden Yazma Ara Yazılımını kullanma yönergeleriyle birlikte URL yeniden yazma işlemi tanıtlanmaktadır.

URL yeniden yazma, önceden tanımlanmış bir veya daha fazla kurala göre istek URL'lerini değiştirme işlemidir. URL yeniden yazma, kaynak konumları ve adresleri arasında bir soyutlama oluşturur, böylece konumlar ve adresler sıkı bir şekilde bağlanmaz. URL yeniden yazma, çeşitli senaryolarda aşağıdakiler için değerlidir:

  • Sunucu kaynaklarını geçici veya kalıcı olarak taşıyın veya değiştirin ve bu kaynaklar için kararlı bulucuları koruyun.
  • farklı uygulamalar arasında veya bir uygulamanın alanları arasında bölünmüş istek işleme.
  • Gelen isteklerde URL kesimlerini kaldırın, ekleyin veya yeniden organize edin.
  • Arama Altyapısı İyileştirmesi (SEO) için genel URL'leri iyileştirin.
  • Ziyaretçilerin bir kaynak isteyerek döndürülen içeriği tahmin etmelerine yardımcı olmak için kolay genel URL'lerin kullanılmasına izin ver.
  • Güvenli olmayan istekleri güvenli uç noktalara yönlendirin.
  • Dış sitenin, varlığı kendi içeriğine bağlayarak başka bir sitede barındırılan statik varlığı kullandığı sık erişimli bağlantıyı engelleyin.

URL yeniden yazma, bir uygulamanın performansını düşürebilir. Kuralların sayısını ve karmaşıklığını sınırlayın.

URL yeniden yönlendirme ve URL yeniden yazma

URL yeniden yönlendirmesi ile URL yeniden yazma arasındaki ifade farkı incedir, ancak istemcilere kaynak sağlamaya yönelik önemli etkilere sahiptir. ASP.NET Core'un URL Yeniden Yazma Ara Yazılımı her iki gereksinimi de karşılayabildi.

URL yeniden yönlendirmesi, istemcinin başlangıçta istenenden farklı bir adresteki bir kaynağa erişmesi talimatının alındığı istemci tarafı işlemi içerir. Bunun için sunucuya gidiş dönüş gerekir. İstemci kaynak için yeni bir istekte bulunduğunda istemciye döndürülen yeniden yönlendirme URL'si tarayıcının adres çubuğunda görünür.

adresine yeniden yönlendirilirse/resource/different-resource, sunucu istemcinin kaynağı /different-resource adresinden alması gerektiğini ve yeniden yönlendirmenin geçici veya kalıcı olduğunu belirten bir durum koduyla yanıt verir.

A WebAPI service endpoint has been temporarily changed from version 1 (v1) to version 2 (v2) on the server. A client makes a request to the service at the version 1 path /v1/api. The server sends back a 302 (Found) response with the new, temporary path for the service at version 2 /v2/api. The client makes a second request to the service at the redirect URL. The server responds with a 200 (OK) status code.

İstekleri farklı bir URL'ye yeniden yönlendirirken, yanıtla birlikte durum kodunu belirterek yeniden yönlendirmenin kalıcı mı yoksa geçici mi olduğunu belirtin:

  • Durum 301 - Moved Permanently kodu, kaynağın yeni, kalıcı bir URL'ye sahip olduğu ve gelecekteki tüm kaynak isteklerinin yeni URL'yi kullanması gerektiği durumlarda kullanılır. İstemci, 301 durum kodu alındığında yanıtı önbelleğe alabilir ve yeniden kullanabilir.

  • Durum 302 - Found kodu, yeniden yönlendirmenin geçici olduğu veya genel olarak değiştirilebilir olduğu durumlarda kullanılır. 302 durum kodu, istemciye URL'yi depolamaması ve gelecekte kullanmaması için gösterir.

Durum kodları hakkında daha fazla bilgi için bkz . RFC 9110: Durum Kodu Tanımları.

URL yeniden yazma, istemcinin isteğinden farklı bir kaynak adresinden kaynak sağlayan sunucu tarafı bir işlemdir. URL'yi yeniden yazmak için sunucuya gidiş dönüş gerekmez. Yeniden yazılan URL istemciye döndürülmüyor ve tarayıcının adres çubuğunda görünmüyor.

için yeniden yazılırsa/resource, sunucu konumundaki kaynağı /different-resourcedahili olarak getirir ve döndürür./different-resource

İstemci, kaynağı yeniden yazılan URL'de alabilse de, istekte bulunduğunda ve yanıtı aldığında kaynağın yeniden yazılan URL'de mevcut olduğu bildirilmiyor.

A WebAPI service endpoint has been changed from version 1 (v1) to version 2 (v2) on the server. A client makes a request to the service at the version 1 path /v1/api. The request URL is rewritten to access the service at the version 2 path /v2/api. The service responds to the client with a 200 (OK) status code.

URL yeniden yazma örnek uygulaması

Örnek uygulamayla URL Yeniden Yazma Ara Yazılımının özelliklerini keşfedin. Uygulama yeniden yönlendirme ve yeniden yazma kuralları uygular ve çeşitli senaryolar için yeniden yönlendirilen veya yeniden yazılan URL'yi gösterir.

URL yeniden yazma ara yazılımı ne zaman kullanılır?

Aşağıdaki yaklaşımlar tatmin edici olmadığında URL Yeniden Yazma Ara Yazılımını kullanın:

Uygulama HTTP.sys sunucusunda barındırıldığında URL yeniden yazma ara yazılımını kullanın.

IIS, Apache ve Nginx'te sunucu tabanlı URL yeniden yazma teknolojilerini kullanmanın başlıca nedenleri şunlardır:

  • Ara yazılım bu modüllerin tüm özelliklerini desteklemez.

    Sunucu modüllerinin bazı özellikleri, IIS Yeniden Yazma modülünün ve IsDirectory kısıtlamaları gibi IsFile ASP.NET Core projeleriyle çalışmaz. Bu senaryolarda bunun yerine ara yazılımı kullanın.

  • Ara yazılımların performansı büyük olasılıkla modüllerin performansıyla eşleşmiyordur.

    Kıyaslama, hangi yaklaşımın performansı en çok düşürüp düşürmediğini veya performansın düşük olup olmadığını kesin olarak bilmenin tek yoludur.

Uzantı ve seçenekler

Yeniden yazma kurallarının her biri için uzantı yöntemleriyle RewriteOptions sınıfının bir örneğini oluşturarak URL yeniden yazma ve yeniden yönlendirme kuralları oluşturun. Birden çok kuralı işlenme sırasına göre zincirleyin. ile RewriteOptions istek işlem hattına UseRewritereklendikçe URL Yeniden Yazma Ara Yazılımına geçirilir:

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

Yukarıdaki kodda MethodRules , kullanıcı tanımlı bir sınıftır. Daha fazla bilgi için bu makaleye bakın RewriteRules.cs .

Www olmayanları www'ye yönlendirme

Üç seçenek, uygulamanın istek olmayanlarıwww uygulamasına yeniden yönlendirmesine wwwizin verir:

  • AddRedirectToWwwPermanent: İstek değilsewww isteği www kalıcı olarak alt etki alanına yeniden yönlendirin. Status308PermanentRedirect durum koduyla yeniden yönlendirir.

  • AddRedirectToWww: Gelen istek değilsewww isteği www alt etki alanına yeniden yönlendirin. Status307TemporaryRedirect durum koduyla yeniden yönlendirir. Aşırı yükleme, yanıt için durum kodunun sağlanmasına izin verir. Durum kodu ataması StatusCodes için sınıfının bir alanını kullanın.

URL yeniden yönlendirme

İstekleri yeniden yönlendirmek için kullanın AddRedirect . İlk parametre, gelen URL'nin yolunda eşleştirme için .NET normal ifadesini (Regex) içerir. İkinci parametre, değiştirme dizesidir. Varsa üçüncü parametre durum kodunu belirtir. Durum kodu belirtilmezse, durum kodu varsayılan olarak 302 - Bulundu olarak ayarlanır ve bu da kaynağın geçici olarak taşındığını veya değiştirildiğini gösterir.

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

Geliştirici araçlarının etkinleştirildiği bir tarayıcıda, yolu /redirect-rule/1234/5678ile örnek uygulamaya bir istekte bulunabilirsiniz. Normal ifade, üzerindeki redirect-rule/(.*)istek yoluyla eşleşir ve yolu ile /redirected/1234/5678değiştirilir. Yeniden yönlendirme URL'si 302 - Bulundu durum koduyla istemciye geri gönderilir. Tarayıcı, tarayıcının adres çubuğunda görünen yeniden yönlendirme URL'sinde yeni bir istekte bulunur. Örnek uygulamadaki hiçbir kural yeniden yönlendirme URL'sinde eşleşmediğinden:

  • İkinci istek, uygulamadan 200 - Tamam yanıtı alır.
  • Yanıtın gövdesi yeniden yönlendirme URL'sini gösterir.

URL yeniden yönlendirildiğinde sunucuya gidiş dönüş yapılır.

Uyarı

Yeniden yönlendirme kuralları oluştururken dikkatli olun. Yeniden yönlendirme kuralları, yeniden yönlendirmeden sonra da dahil olmak üzere uygulamaya yapılan her istekte değerlendirilir. Yanlışlıkla sonsuz yeniden yönlendirmeler döngüsü oluşturmak kolaydır.

İfadenin parantez içinde yer alan bölümüne yakalama grubu adı verilir. İfadenin noktası (.) herhangi bir karakterle eşleşsin anlamına gelir. Yıldız işareti (*), önceki karakterle sıfır veya daha fazla kez eşleşdiğini gösterir. Bu nedenle, URL'nin son iki yol kesimi olan 1234/5678yakalama grubu (.*)tarafından yakalanır. sonrasında istek URL'sinde redirect-rule/ sağlanan tüm değerler bu tek yakalama grubu tarafından yakalanır.

Değiştirilen dizede, yakalanan gruplar dizeye dolar işareti ($) ve ardından yakalamanın sıra numarası ile eklenir. İlk yakalama grubu değeri ile $1elde edilir, ikincisi ile elde $2edilir ve normal ifadedeki yakalama grupları için sırayla devam ederler. içinde yeniden yönlendirme kuralı normal ifadesinde redirect-rule/(.*)yalnızca bir yakalanan grup vardır, bu nedenle değiştirme dizesinde yalnızca bir eklenen grup vardır; bu da olur $1. Kural uygulandığında URL olur /redirected/1234/5678.

Ağ sekmesindeki tarayıcı araçlarıyla deneyin /redirect-rule/1234/5678 .

URL güvenli bir uç noktaya yeniden yönlendirme

HTTPS protokolunu kullanarak HTTP isteklerini aynı ana bilgisayara ve yola yeniden yönlendirmek için kullanın AddRedirectToHttps . Durum kodu sağlanmazsa ara yazılım varsayılan olarak 302 - Bulundu olur. Bağlantı noktası sağlanmadıysa:

  • Ara yazılım varsayılan olarak olarak gösterilir null.
  • Düzen (HTTPS protokolü) olarak değişir https ve istemci 443 numaralı bağlantı noktasında kaynağa erişir.

Aşağıdaki örnekte durum kodunun 301 - Moved Permanently nasıl ayarlanacağı ve bağlantı noktasının localhost üzerinde tarafından kullanılan HTTPS bağlantı noktası olarak Kestrel nasıl değiştireceği gösterilmektedir. Üretimde HTTPS bağlantı noktası null olarak ayarlanır:

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

int? localhostHTTPSport = null;
if (app.Environment.IsDevelopment())
{
    localhostHTTPSport = Int32.Parse(Environment.GetEnvironmentVariable(
                   "ASPNETCORE_URLS")!.Split(new Char[] { ':', ';' })[2]);
}

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        // localhostHTTPport not needed for production, used only with localhost.
        .AddRedirectToHttps(301, localhostHTTPSport)
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

Güvenli olmayan istekleri 443 numaralı bağlantı noktasında güvenli HTTPS protokolüyle aynı ana bilgisayara ve yola yönlendirmek için kullanın AddRedirectToHttpsPermanent . Ara yazılım durum kodunu olarak 301 - Moved Permanentlyayarlar.

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

Dekont

Ek yeniden yönlendirme kuralları gerekmeden güvenli bir uç noktaya yeniden yönlendirme yaparken HTTPS Yeniden Yönlendirme Ara Yazılımı kullanmanızı öneririz. Daha fazla bilgi için bkz . HTTPS'yi zorunlu kılma.

Örnek uygulama, veya AddRedirectToHttpsPermanent'nin nasıl kullanılacağını AddRedirectToHttps gösterir. konumunda http://redirect6.azurewebsites.net/iis-rules-rewrite/xyzuygulamaya güvenli olmayan bir HTTP isteği oluşturun. localhost ile HTTP'den HTTPS'ye yeniden yönlendirmeyi test ederken:

  • HTTPS URL'sinden farklı bir bağlantı noktasına sahip HTTP URL'sini kullanın. HTTP URL'si dosyadadır Properties/launchSettings.json .
  • s localhost HTTP'de HTTPS bağlantı noktasına yanıt vermediğinden öğesi kaldırılamıyorhttps://localhost/{port}.

Aşağıdaki görüntüde, önceki kodu kullanmaya yönelik bir isteğin http://redirect6.azurewebsites.net/iis-rules-rewrite/xyz F12 tarayıcı araçları görüntüsü gösterilmektedir:

Browser window with developer tools tracking the requests and responses: Add redirect to HTTPS

URL yeniden yazma

URL'leri yeniden yazmaya yönelik bir kural oluşturmak için kullanın AddRewrite . İlk parametre, gelen URL yolunda eşleştirme için normal ifadeyi içerir. İkinci parametre, değiştirme dizesidir. Üçüncü parametre, skipRemainingRules: {true|false}geçerli kural uygulanırsa ek yeniden yazma kurallarının atlanıp atlanmayacağını ara yazılıma gösterir.

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

şu isteği deneyin: https://redirect6.azurewebsites.net/rewrite-rule/1234/5678

İfadenin başındaki şapka işareti (^), eşleştirmenin URL yolunun başında başladığı anlamına gelir.

Yeniden yönlendirme kuralına sahip önceki örnekte normal redirect-rule/(.*)ifadenin başında şapka işareti (^) yoktur. Bu nedenle, başarılı bir eşleşme için yolda herhangi bir karakter önce redirect-rule/ gelebilir.

Path Eşleştir
/redirect-rule/1234/5678 Evet
/my-cool-redirect-rule/1234/5678 Evet
/anotherredirect-rule/1234/5678 Evet

yeniden yazma kuralı, ^rewrite-rule/(\d+)/(\d+)yalnızca ile başlıyorsa yollarla rewrite-rule/eşleşir. Aşağıdaki tabloda, eşleştirme farkını not edin.

Path Eşleştir
/rewrite-rule/1234/5678 Evet
/my-cool-rewrite-rule/1234/5678 Hayı
/anotherrewrite-rule/1234/5678 Hayır

İfadenin ^rewrite-rule/ bölümünü takip eden iki yakalama grubu vardır: (\d+)/(\d+). İşaretler \dbir rakamla (sayı) eşleşir. Artı işareti (+), önceki karakterden biriyle veya daha fazlası ile eşleşen anlamına gelir. Bu nedenle, URL'nin bir sayı içermesi ve ardından eğik çizgi ve ardından başka bir sayı içermesi gerekir. Bu yakalama grupları, yeniden yazılan URL'ye ve $2olarak $1 eklenir. Yeniden yazma kuralı değiştirme dizesi, yakalanan grupları sorgu dizesine yerleştirir. kaynağı konumunda /rewritten?var1=1234&var2=5678döndürmek için istenen yol /rewrite-rule/1234/5678 yeniden yazılır. Özgün istekte bir sorgu dizesi varsa, URL yeniden yazıldığında korunur.

Kaynağı döndürmek için sunucuya gidiş dönüş yoktur. Kaynak varsa, getirilir ve 200 - Tamam durum koduyla istemciye döndürülür. İstemci yeniden yönlendirilemediğinden, tarayıcının adres çubuğundaki URL değişmez. İstemciler sunucuda url yeniden yazma işleminin gerçekleştiğini algılayamaz.

URL yeniden yazma ve yeniden yönlendirme için performans ipuçları

En hızlı yanıt için:

  • En sık eşleşen kuraldan en az eşleşen kurala yeniden yazma kurallarını sırala.
  • Eşleştirme kuralları hesaplama açısından pahalı olduğundan ve uygulama yanıt süresini artırdığından mümkün olduğunca kullanın skipRemainingRules: true . Bir eşleşme oluştuğunda ve ek kural işleme gerekli olmadığında kalan kuralların işlenmesini atlayın.

Uyarı

Kötü amaçlı bir kullanıcı, Hizmet Reddi saldırısına neden olmak için RegularExpressions pahalı işleme girişi sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri. Örneğin RedirectRule ve RewriteRule sınıflarının her ikisi de bir saniyelik zaman aşımına neden olur.

Apache mod_rewrite

ile AddApacheModRewriteApache mod_rewrite kuralları uygulama. Kural dosyasının uygulamayla dağıtıldığından emin olun. mod_rewrite kuralları hakkında daha fazla bilgi ve örnek için bkz . Apache mod_rewrite.

, StreamReader ApacheModRewrite.txt kural dosyasındaki kuralları okumak için kullanılır:

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

Örnek uygulama, 'den /apache-mod-rules-redirect/(.\*) istekleri'ne /redirected?id=$1yönlendirir. Yanıt durum kodu : 302 - Bulundu.

# Rewrite path with additional sub directory
RewriteRule ^/apache-mod-rules-redirect/(.*) /redirected?id=$1 [L,R=302]

şu isteği deneyin: https://redirect6.azurewebsites.net/apache-mod-rules-redirect/1234

Apache ara yazılımı aşağıdaki Apache mod_rewrite sunucu değişkenlerini destekler:

  • CONN_REMOTE_ADDR
  • HTTP_ACCEPT
  • HTTP_CONNECTION
  • HTTP_COOKIE
  • HTTP_FORWARDED
  • HTTP_HOST
  • HTTP_REFERER
  • HTTP_USER_AGENT
  • HTTPS
  • IPV6
  • QUERY_STRING
  • REMOTE_ADDR
  • REMOTE_PORT
  • REQUEST_FILENAME
  • REQUEST_METHOD
  • REQUEST_SCHEME
  • REQUEST_URI
  • SCRIPT_FILENAME
  • SERVER_ADDR
  • SERVER_PORT
  • SERVER_PROTOCOL
  • TIME
  • TIME_DAY
  • TIME_HOUR
  • TIME_MIN
  • TIME_MON
  • TIME_SEC
  • TIME_WDAY
  • TIME_YEAR

IIS URL Yeniden Yazma Modülü kuralları

IIS URL Yeniden Yazma Modülü için geçerli olan aynı kural kümesini kullanmak için kullanın AddIISUrlRewrite. Kural dosyasının uygulamayla dağıtıldığından emin olun. Ara yazılımı Windows Server IIS'de çalışırken uygulamanın web.config dosyasını kullanmaya yönlendirmeyin. IIS ile, IIS Yeniden Yazma modülüyle çakışmaları önlemek için bu kurallar uygulamanın web.config dosyasının dışında depolanmalıdır. IIS URL Yeniden Yazma Modülü kuralları hakkında daha fazla bilgi ve örnek için bkz . Url Yeniden Yazma Modülü 2.0 kullanma ve URL Yeniden Yazma Modülü Yapılandırma Başvurusu.

, StreamReader kurallar dosyasından kuralları IISUrlRewrite.xml okumak için kullanılır:

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

Örnek uygulama, 'den adresine /iis-rules-rewrite/(.*)/rewritten?id=$1istekleri yeniden yazar. Yanıt, istemciye 200 - Tamam durum koduyla gönderilir.

<rewrite>
  <rules>
    <rule name="Rewrite segment to id querystring" stopProcessing="true">
      <match url="^iis-rules-rewrite/(.*)$" />
      <action type="Rewrite" url="rewritten?id={R:1}" appendQueryString="false"/>
    </rule>
  </rules>
</rewrite>

şu isteği deneyin: https://redirect6.azurewebsites.net/iis-rules-rewrite/xyz

Uygulamayı istenmeyen yollarla etkileyen sunucu düzeyinde kurallar yapılandırılmış etkin bir IIS Yeniden Yazma Modülüne sahip uygulamalar:

  • Uygulama için IIS Yeniden Yazma Modülünü devre dışı bırakmayı göz önünde bulundurun.
  • Daha fazla bilgi için bkz . IIS modüllerini devre dışı bırakma.

Desteklenmeyen özellikler

Ara yazılım aşağıdaki IIS URL Yeniden Yazma Modülü özelliklerini desteklemez:

  • Giden Kuralları
  • Özel Sunucu Değişkenleri
  • Joker karakterler
  • LogRewrittenUrl

Desteklenen sunucu değişkenleri

Ara yazılım aşağıdaki IIS URL Yeniden Yazma Modülü sunucu değişkenlerini destekler:

  • CONTENT_LENGTH
  • CONTENT_TYPE
  • HTTP_ACCEPT
  • HTTP_CONNECTION
  • HTTP_COOKIE
  • HTTP_HOST
  • HTTP_REFERER
  • HTTP_URL
  • HTTP_USER_AGENT
  • HTTPS
  • LOCAL_ADDR
  • QUERY_STRING
  • REMOTE_ADDR
  • REMOTE_PORT
  • REQUEST_FILENAME
  • REQUEST_URI

IFileProvider aracılığıyla PhysicalFileProviderelde edilebilir. Bu yaklaşım, yeniden yazma kuralları dosyalarının konumu için daha fazla esneklik sağlayabilir. Yeniden yazma kuralları dosyalarının sağlanan yolda sunucuya dağıtıldığından emin olun.

var fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());

Yöntem tabanlı kural

Bir yöntemde özel kural mantığı uygulamak için kullanın Add . AddRewriteContextyeniden yönlendirme yöntemlerinde kullanmak üzere öğesini kullanıma HttpContext sunan öğesini kullanıma sunar. özelliği, RewriteContext.Result ek işlem hattı işlemenin nasıl işleneceğini belirler. Değeri aşağıdaki tabloda açıklanan alanlardan birine RuleResult ayarlayın.

Bağlam sonucunu yeniden yazma Eylem
RuleResult.ContinueRules (varsayılan) Kuralları uygulamaya devam edin.
RuleResult.EndResponse Kuralları uygulamayı durdurun ve yanıtı gönderin.
RuleResult.SkipRemainingRules Kuralları uygulamayı durdurun ve bağlamı bir sonraki ara yazılıma gönderin.
using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

Örnek uygulama, ile .xmlbiten yollar için istekleri yeniden yönlendiren bir yöntem gösterir. için /file.xmlbir istek yapıldığında:

  • İstek şu konuma yönlendirilir: /xmlfiles/file.xml
  • Durum kodu olarak 301 - Moved Permanentlyayarlanır. Tarayıcı için /xmlfiles/file.xmlyeni bir istek yaptığında, Statik Dosya Ara Yazılımı dosyayı wwwroot/xmlfiles klasöründen istemciye hizmet eder . Yeniden yönlendirme için yanıtın durum kodunu açıkça ayarlayın. Aksi takdirde, 200 - Tamam durum kodu döndürülür ve yeniden yönlendirme istemcide gerçekleşmez.

RewriteRules.cs:

public static void RedirectXmlFileRequests(RewriteContext context)
{
    var request = context.HttpContext.Request;

    // Because the client is redirecting back to the same app, stop 
    // processing if the request has already been redirected.
    if (request.Path.StartsWithSegments(new PathString("/xmlfiles")) ||
        request.Path.Value==null)
    {
        return;
    }

    if (request.Path.Value.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
    {
        var response = context.HttpContext.Response;
        response.StatusCode = (int) HttpStatusCode.MovedPermanently;
        context.Result = RuleResult.EndResponse;
        response.Headers[HeaderNames.Location] = 
            "/xmlfiles" + request.Path + request.QueryString;
    }
}

Bu yaklaşım istekleri de yeniden yazabilir. Örnek uygulama, wwwroot klasöründen file.txt metin dosyasını sunmak için herhangi bir metin dosyası isteğinin yolunu yeniden yazmayı gösterir. Statik Dosya Ara Yazılımı, güncelleştirilmiş istek yoluna göre dosyaya hizmet eder:

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

RewriteRules.cs:

public static void RewriteTextFileRequests(RewriteContext context)
{
    var request = context.HttpContext.Request;

    if (request.Path.Value != null &&
        request.Path.Value.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
    {
        context.Result = RuleResult.SkipRemainingRules;
        request.Path = "/file.txt";
    }
}

IRule tabanlı kural

Arabirimini uygulayan IRule bir sınıfta kural mantığını kullanmak için kullanınAdd. IRule yöntem tabanlı kural yaklaşımını kullanma üzerinde daha fazla esneklik sağlar. Uygulama sınıfı, yöntemi için ApplyRule parametrelerin geçirilmesine izin veren bir oluşturucu içerebilir.

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

ve newPath için örnek uygulamadaki extension parametrelerin değerleri çeşitli koşulları karşılamak için denetlenmektedir. extension bir değer içermeli ve değer , .jpgveya .gifolmalıdır.png. newPath geçerli değilse, bir ArgumentException oluşturulur. için image.pngbir istek yapılırsa, istek adresine /png-images/image.pngyönlendirilir. için image.jpgbir istek yapılırsa, istek adresine /jpg-images/image.jpgyönlendirilir. Durum kodu olarak 301 - Moved Permanentlyayarlanır ve context.Result kuralları işlemeyi durduracak ve yanıtı gönderecek şekilde ayarlanır.

public class RedirectImageRequests : IRule
{
    private readonly string _extension;
    private readonly PathString _newPath;

    public RedirectImageRequests(string extension, string newPath)
    {
        if (string.IsNullOrEmpty(extension))
        {
            throw new ArgumentException(nameof(extension));
        }

        if (!Regex.IsMatch(extension, @"^\.(png|jpg|gif)$"))
        {
            throw new ArgumentException("Invalid extension", nameof(extension));
        }

        if (!Regex.IsMatch(newPath, @"(/[A-Za-z0-9]+)+?"))
        {
            throw new ArgumentException("Invalid path", nameof(newPath));
        }

        _extension = extension;
        _newPath = new PathString(newPath);
    }

    public void ApplyRule(RewriteContext context)
    {
        var request = context.HttpContext.Request;

        // Because we're redirecting back to the same app, stop 
        // processing if the request has already been redirected
        if (request.Path.StartsWithSegments(new PathString(_newPath)) ||
            request.Path.Value == null)
        {
            return;
        }

        if (request.Path.Value.EndsWith(_extension, StringComparison.OrdinalIgnoreCase))
        {
            var response = context.HttpContext.Response;
            response.StatusCode = (int) HttpStatusCode.MovedPermanently;
            context.Result = RuleResult.EndResponse;
            response.Headers[HeaderNames.Location] = 
                _newPath + request.Path + request.QueryString;
        }
    }
}

Şunu deneyin:

  • PNG isteği: https://redirect6.azurewebsites.net/image.png
  • JPG isteği: https://redirect6.azurewebsites.net/image.jpg

Regex örnekleri

Goal Regex Dizesi &
Eşleşme Örneği
Değiştirme Dizesi &
Çıkış Örneği
Sorgu dizesine yolu yeniden yazma ^path/(.*)/(.*)
/path/abc/123
path?var1=$1&var2=$2
/path?var1=abc&var2=123
Şerit sondaki eğik çizgi ^path2/(.*)/$
/path2/xyz/
$1
/path2/xyz
Sondaki eğik çizgiyi zorlama ^path3/(.*[^/])$
/path3/xyz
$1/
/path3/xyz/
Belirli istekleri yeniden yazmaktan kaçının ^(.*)(?<!\.axd)$ Veya
^(?!.*\.axd$)(.*)$
Evet: /path4/resource.htm
No: /path4/resource.axd
rewritten/$1
/rewritten/resource.htm
/resource.axd
URL kesimlerini yeniden düzenleme path5/(.*)/(.*)/(.*)
path5/1/2/3
path5/$3/$2/$1
path5/3/2/1
URL kesimini değiştirme ^path6/(.*)/segment2/(.*)
^path6/segment1/segment2/segment3
path6/$1/replaced/$2
/path6/segment1/replaced/segment3

Yukarıdaki tablodaki bağlantılar, Azure'a dağıtılan aşağıdaki kodu kullanır:

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)

        // Rewrite path to QS.
        .AddRewrite(@"^path/(.*)/(.*)", "path?var1=$1&var2=$2",
            skipRemainingRules: true)
        // Skip trailing slash.
        .AddRewrite(@"^path2/(.*)/$", "path2/$1",
            skipRemainingRules: true)
         // Enforce trailing slash.
         .AddRewrite(@"^path3/(.*[^/])$", "path3/$1/",
            skipRemainingRules: true)
         // Avoid rewriting specific requests.
         .AddRewrite(@"^path4/(.*)(?<!\.axd)$", "rewritten/$1",
            skipRemainingRules: true)
         // Rearrange URL segments
         .AddRewrite(@"^path5/(.*)/(.*)/(.*)", "path5/$3/$2/$1",
            skipRemainingRules: true)
          // Replace a URL segment
          .AddRewrite(@"^path6/(.*)/segment2/(.*)", "path6/$1/replaced/$2",
            skipRemainingRules: true)

        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

Yukarıdaki normal ifade örneklerinin çoğunda değişmez değer path , dağıtılan örnek için benzersiz sınanabilir yeniden yazma kuralları oluşturmak için kullanılır. Normal ifade genellikle içermez path. Örneğin, bu normal ifade örnekleri tablosuna bakın.

Bu belgede, ASP.NET Core uygulamalarında URL Yeniden Yazma Ara Yazılımını kullanma yönergeleriyle birlikte URL yeniden yazma tanıtılması sağlanır.

URL yeniden yazma, önceden tanımlanmış bir veya daha fazla kurala göre istek URL'lerini değiştirme işlemidir. URL yeniden yazma, kaynak konumları ve adresleri arasında bir soyutlama oluşturur, böylece konumlar ve adresler sıkı bir şekilde bağlanmaz. URL yeniden yazma, çeşitli senaryolarda aşağıdakiler için değerlidir:

  • Sunucu kaynaklarını geçici veya kalıcı olarak taşıyın veya değiştirin ve bu kaynaklar için kararlı bulucuları koruyun.
  • farklı uygulamalar arasında veya bir uygulamanın alanları arasında bölünmüş istek işleme.
  • Gelen isteklerde URL kesimlerini kaldırın, ekleyin veya yeniden organize edin.
  • Arama Altyapısı İyileştirmesi (SEO) için genel URL'leri iyileştirin.
  • Ziyaretçilerin bir kaynak isteyerek döndürülen içeriği tahmin etmelerine yardımcı olmak için kolay genel URL'lerin kullanılmasına izin ver.
  • Güvenli olmayan istekleri güvenli uç noktalara yönlendirin.
  • Dış sitenin, varlığı kendi içeriğine bağlayarak başka bir sitede barındırılan statik varlığı kullandığı sık erişimli bağlantıyı engelleyin.

Dekont

URL yeniden yazma, bir uygulamanın performansını düşürebilir. Mümkün olduğunda kuralların sayısını ve karmaşıklığını sınırlayın.

Örnek kodu görüntüleme veya indirme (indirme)

URL yeniden yönlendirme ve URL yeniden yazma

URL yeniden yönlendirmesi ile URL yeniden yazma arasındaki ifade farkı incedir, ancak istemcilere kaynak sağlamaya yönelik önemli etkilere sahiptir. ASP.NET Core'un URL Yeniden Yazma Ara Yazılımı her iki gereksinimi de karşılayabildi.

URL yeniden yönlendirmesi, istemcinin başlangıçta istenenden farklı bir adresteki bir kaynağa erişmesi talimatının alındığı istemci tarafı işlemi içerir. Bunun için sunucuya gidiş dönüş gerekir. İstemci kaynak için yeni bir istekte bulunduğunda istemciye döndürülen yeniden yönlendirme URL'si tarayıcının adres çubuğunda görünür.

adresine yeniden yönlendirilirse/resource/different-resource, sunucu istemcinin kaynağı /different-resource adresinden alması gerektiğini ve yeniden yönlendirmenin geçici veya kalıcı olduğunu belirten bir durum koduyla yanıt verir.

A WebAPI service endpoint has been temporarily changed from version 1 (v1) to version 2 (v2) on the server. A client makes a request to the service at the version 1 path /v1/api. The server sends back a 302 (Found) response with the new, temporary path for the service at version 2 /v2/api. The client makes a second request to the service at the redirect URL. The server responds with a 200 (OK) status code.

İstekleri farklı bir URL'ye yeniden yönlendirirken, yanıtla birlikte durum kodunu belirterek yeniden yönlendirmenin kalıcı mı yoksa geçici mi olduğunu belirtin:

  • Durum 301 - Moved Permanently kodu, kaynağın yeni, kalıcı bir URL'ye sahip olduğu ve istemciye kaynak için gelecekteki tüm isteklerin yeni URL'yi kullanması gerektiğini bildirmek istediğiniz durumlarda kullanılır. İstemci, 301 durum kodu alındığında yanıtı önbelleğe alabilir ve yeniden kullanabilir.

  • Yeniden yönlendirmenin geçici olduğu veya genellikle değiştirilebilir olduğu 302 - Bulunan durum kodu kullanılır. 302 durum kodu, istemciye URL'yi depolamaması ve gelecekte kullanmaması için gösterir.

Durum kodları hakkında daha fazla bilgi için bkz . RFC 9110: Durum Kodu Tanımları.

URL yeniden yazma, istemcinin isteğinden farklı bir kaynak adresinden kaynak sağlayan sunucu tarafı bir işlemdir. URL'yi yeniden yazmak için sunucuya gidiş dönüş gerekmez. Yeniden yazılan URL istemciye döndürülmüyor ve tarayıcının adres çubuğunda görünmüyor.

için yeniden yazılırsa/resource, sunucu konumundaki kaynağı /different-resourcedahili olarak getirir ve döndürür./different-resource

İstemci, kaynağı yeniden yazılan URL'de alabilse de, istekte bulunduğunda ve yanıtı aldığında kaynağın yeniden yazılan URL'de mevcut olduğu bildirilmiyor.

A WebAPI service endpoint has been changed from version 1 (v1) to version 2 (v2) on the server. A client makes a request to the service at the version 1 path /v1/api. The request URL is rewritten to access the service at the version 2 path /v2/api. The service responds to the client with a 200 (OK) status code.

URL yeniden yazma örnek uygulaması

Örnek uygulamayla URL Yeniden Yazma Ara Yazılımının özelliklerini keşfedebilirsiniz. Uygulama yeniden yönlendirme ve yeniden yazma kuralları uygular ve çeşitli senaryolar için yeniden yönlendirilen veya yeniden yazılan URL'yi gösterir.

URL yeniden yazma ara yazılımı ne zaman kullanılır?

Aşağıdaki yaklaşımları kullanamıyorsanız URL Yeniden Yazma Ara Yazılımını kullanın:

Uygulama HTTP.sys sunucusunda barındırıldığında URL yeniden yazma ara yazılımını kullanın.

IIS, Apache ve Nginx'te sunucu tabanlı URL yeniden yazma teknolojilerini kullanmanın başlıca nedenleri şunlardır:

  • Ara yazılım bu modüllerin tüm özelliklerini desteklemez.

    Sunucu modüllerinin bazı özellikleri, IIS Yeniden Yazma modülünün ve IsDirectory kısıtlamaları gibi IsFile ASP.NET Core projeleriyle çalışmaz. Bu senaryolarda bunun yerine ara yazılımı kullanın.

  • Ara yazılımların performansı büyük olasılıkla modüllerin performansıyla eşleşmiyordur.

    Kıyaslama, hangi yaklaşımın performansı en çok düşürüp düşürmediğini veya performansın düşürülmesinin göz ardı edilebilir olup olmadığını bilmenin tek yoludur.

Paket

URL Yeniden Yazma Ara Yazılımı, ASP.NET Core uygulamalarına örtük olarak dahil edilen Microsoft.AspNetCore.Rewrite paketi tarafından sağlanır.

Uzantı ve seçenekler

Yeniden yazma kurallarınızın her biri için uzantı yöntemleriyle RewriteOptions sınıfının bir örneğini oluşturarak URL yeniden yazma ve yeniden yönlendirme kuralları oluşturun. Birden çok kuralı işlenmelerini istediğiniz sırayla zincirleyin. ile RewriteOptions istek işlem hattına UseRewritereklendikçe URL Yeniden Yazma Ara Yazılımına geçirilir:

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Www olmayanları www'ye yönlendirme

Üç seçenek, uygulamanın istek olmayanlarıwww uygulamasına yeniden yönlendirmesine wwwizin verir:

  • AddRedirectToWwwPermanent: İstek değilsewww isteği www kalıcı olarak alt etki alanına yeniden yönlendirin. Status308PermanentRedirect durum koduyla yeniden yönlendirir.

  • AddRedirectToWww: Gelen istek değilsewww isteği www alt etki alanına yeniden yönlendirin. Status307TemporaryRedirect durum koduyla yeniden yönlendirir. Aşırı yükleme, yanıt için durum kodunu sağlamanıza izin verir. Durum kodu ataması StatusCodes için sınıfının bir alanını kullanın.

URL yeniden yönlendirme

İstekleri yeniden yönlendirmek için kullanın AddRedirect . İlk parametre, gelen URL'nin yolunda eşleştirmek için Regex'inizi içerir. İkinci parametre, değiştirme dizesidir. Varsa üçüncü parametre durum kodunu belirtir. Durum kodunu belirtmezseniz, durum kodu varsayılan olarak 302 - Bulundu olarak ayarlanır ve bu da kaynağın geçici olarak taşındığını veya değiştirildiğini gösterir.

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Geliştirici araçlarının etkinleştirildiği bir tarayıcıda, yolu /redirect-rule/1234/5678ile örnek uygulamaya bir istekte bulunabilirsiniz. Regex, üzerindeki redirect-rule/(.*)istek yoluyla eşleşir ve yolu ile /redirected/1234/5678değiştirilir. Yeniden yönlendirme URL'si 302 - Bulundu durum koduyla istemciye geri gönderilir. Tarayıcı, tarayıcının adres çubuğunda görünen yeniden yönlendirme URL'sinde yeni bir istekte bulunur. Örnek uygulamadaki hiçbir kural yeniden yönlendirme URL'sinde eşleşmediğinden:

  • İkinci istek, uygulamadan 200 - Tamam yanıtı alır.
  • Yanıtın gövdesi yeniden yönlendirme URL'sini gösterir.

URL yeniden yönlendirildiğinde sunucuya gidiş dönüş yapılır.

Uyarı

Yeniden yönlendirme kuralları oluştururken dikkatli olun. Yeniden yönlendirme kuralları, yeniden yönlendirmeden sonra da dahil olmak üzere uygulamaya yapılan her istekte değerlendirilir. Yanlışlıkla sonsuz yeniden yönlendirmeler döngüsü oluşturmak kolaydır.

Özgün İstek: /redirect-rule/1234/5678

Browser window with developer tools tracking the requests and responses: Add redirect

İfadenin parantez içinde yer alan bölümüne yakalama grubu adı verilir. İfadenin noktası (.) herhangi bir karakterle eşleşsin anlamına gelir. Yıldız işareti (*), önceki karakterle sıfır veya daha fazla kez eşleşdiğini gösterir. Bu nedenle, URL'nin son iki yol kesimi olan 1234/5678yakalama grubu (.*)tarafından yakalanır. İstek URL'sinde redirect-rule/ sağladığınız tüm değerler bu tek yakalama grubu tarafından yakalanır.

Değiştirilen dizede, yakalanan gruplar dizeye dolar işareti ($) ve ardından yakalamanın sıra numarası ile eklenir. İlk yakalama grubu değeri ile $1elde edilir, ikincisi ile elde $2edilir ve kayıt defterinizdeki yakalama grupları için sırayla devam eder. Örnek uygulamadaki yeniden yönlendirme kuralı reex'inde yalnızca bir yakalanan grup vardır, bu nedenle değiştirme dizesinde eklenen tek bir grup vardır; bu da olur $1. Kural uygulandığında URL olur /redirected/1234/5678.

URL güvenli bir uç noktaya yeniden yönlendirme

HTTPS protokolunu kullanarak HTTP isteklerini aynı ana bilgisayara ve yola yeniden yönlendirmek için kullanın AddRedirectToHttps . Durum kodu sağlanmazsa ara yazılım varsayılan olarak 302 - Bulundu olur. Bağlantı noktası sağlanmadıysa:

  • Ara yazılım varsayılan olarak olarak gösterilir null.
  • Düzen (HTTPS protokolü) olarak değişir https ve istemci 443 numaralı bağlantı noktasında kaynağa erişir.

Aşağıdaki örnekte durum kodunun 301 - Moved Permanently nasıl ayarlanacağı ve bağlantı noktasının 5001 olarak nasıl değiştireceği gösterilmektedir.

public void Configure(IApplicationBuilder app)
{
    var options = new RewriteOptions()
        .AddRedirectToHttps(301, 5001);

    app.UseRewriter(options);
}

Güvenli olmayan istekleri 443 numaralı bağlantı noktasında güvenli HTTPS protokolüyle aynı ana bilgisayara ve yola yönlendirmek için kullanın AddRedirectToHttpsPermanent . Ara yazılım durum kodunu olarak 301 - Moved Permanentlyayarlar.

public void Configure(IApplicationBuilder app)
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent();

    app.UseRewriter(options);
}

Dekont

Ek yeniden yönlendirme kuralları gerekmeden güvenli bir uç noktaya yeniden yönlendirme yaparken HTTPS Yeniden Yönlendirme Ara Yazılımı kullanmanızı öneririz. Daha fazla bilgi için HTTPS'yi zorunlu kılma konusuna bakın.

Örnek uygulama veya AddRedirectToHttpsPermanent'nin nasıl kullanılacağını AddRedirectToHttps gösterebilen bir uygulamadır. uzantısı yöntemini öğesine RewriteOptionsekleyin. Herhangi bir URL'de uygulamaya güvenli olmayan bir istekte bulunın. Otomatik olarak imzalanan sertifikaya güvenilmeyen tarayıcı güvenlik uyarısını kapatın veya sertifikaya güvenmek için bir özel durum oluşturun.

kullanarak AddRedirectToHttps(301, 5001)Özgün İstek: http://localhost:5000/secure

Browser window with developer tools tracking the requests and responses: Add redirect to HTTPS

kullanarak AddRedirectToHttpsPermanentÖzgün İstek: http://localhost:5000/secure

Browser window with developer tools tracking the requests and responses: Add redirect to HTTPS permanent

URL yeniden yazma

URL'leri yeniden yazmaya yönelik bir kural oluşturmak için kullanın AddRewrite . İlk parametre, gelen URL yolunda eşleştirme için regex'i içerir. İkinci parametre, değiştirme dizesidir. Üçüncü parametre, skipRemainingRules: {true|false}geçerli kural uygulanırsa ek yeniden yazma kurallarının atlanıp atlanmayacağını ara yazılıma gösterir.

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Özgün İstek: /rewrite-rule/1234/5678

Browser window with developer tools tracking the request and response: Add rewrite

İfadenin başındaki karat (^), eşleştirmenin URL yolunun başında başladığı anlamına gelir.

Önceki örnekte yeniden yönlendirme kuralıyla redirect-rule/(.*)birlikte, regex'in başında karat (^) yoktur. Bu nedenle, başarılı bir eşleşme için yolda herhangi bir karakter önce redirect-rule/ gelebilir.

Path Eşleştir
/redirect-rule/1234/5678 Evet
/my-cool-redirect-rule/1234/5678 Evet
/anotherredirect-rule/1234/5678 Evet

yeniden yazma kuralı, ^rewrite-rule/(\d+)/(\d+)yalnızca ile başlıyorsa yollarla rewrite-rule/eşleşir. Aşağıdaki tabloda, eşleştirme farkını not edin.

Path Eşleştir
/rewrite-rule/1234/5678 Evet
/my-cool-rewrite-rule/1234/5678 Hayı
/anotherrewrite-rule/1234/5678 Hayır

İfadenin ^rewrite-rule/ bölümünü takip eden iki yakalama grubu vardır: (\d+)/(\d+). İşaretler \dbir rakamla (sayı) eşleşir. Artı işareti (+), önceki karakterden biriyle veya daha fazlası ile eşleşen anlamına gelir. Bu nedenle, URL'nin bir sayı içermesi ve ardından eğik çizgi ve ardından başka bir sayı içermesi gerekir. Bu yakalama grupları, yeniden yazılan URL'ye ve $2olarak $1 eklenir. Yeniden yazma kuralı değiştirme dizesi, yakalanan grupları sorgu dizesine yerleştirir. kaynağı adresinden almak /rewritten?var1=1234&var2=5678için istenen yolu /rewrite-rule/1234/5678 yeniden yazılır. Özgün istekte bir sorgu dizesi varsa, URL yeniden yazıldığında korunur.

Kaynağı almak için sunucuya gidiş dönüş yoktur. Kaynak varsa, getirilir ve 200 - Tamam durum koduyla istemciye döndürülür. İstemci yeniden yönlendirilemediğinden, tarayıcının adres çubuğundaki URL değişmez. İstemciler sunucuda url yeniden yazma işleminin gerçekleştiğini algılayamaz.

Dekont

Eşleştirme kuralları hesaplama açısından pahalı olduğundan ve uygulama yanıt süresini artırdığından mümkün olduğunca kullanın skipRemainingRules: true . En hızlı uygulama yanıtı için:

  • En sık eşleşen kuraldan en az eşleşen kurala yeniden yazma kurallarını sırala.
  • Bir eşleşme oluştuğunda ve ek kural işleme gerekli olmadığında kalan kuralların işlenmesini atlayın.

Apache mod_rewrite

ile AddApacheModRewriteApache mod_rewrite kuralları uygulama. Kural dosyasının uygulamayla dağıtıldığından emin olun. mod_rewrite kuralları hakkında daha fazla bilgi ve örnek için bkz . Apache mod_rewrite.

, StreamReader ApacheModRewrite.txt kural dosyasındaki kuralları okumak için kullanılır:

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Örnek uygulama, 'den /apache-mod-rules-redirect/(.\*) istekleri'ne /redirected?id=$1yönlendirir. Yanıt durum kodu : 302 - Bulundu.

# Rewrite path with additional sub directory
RewriteRule ^/apache-mod-rules-redirect/(.*) /redirected?id=$1 [L,R=302]

Özgün İstek: /apache-mod-rules-redirect/1234

Browser window with developer tools tracking the requests and responses: Add Apache mod redirect

Ara yazılım aşağıdaki Apache mod_rewrite sunucu değişkenlerini destekler:

  • CONN_REMOTE_ADDR
  • HTTP_ACCEPT
  • HTTP_CONNECTION
  • HTTP_COOKIE
  • HTTP_FORWARDED
  • HTTP_HOST
  • HTTP_REFERER
  • HTTP_USER_AGENT
  • HTTPS
  • IPV6
  • QUERY_STRING
  • REMOTE_ADDR
  • REMOTE_PORT
  • REQUEST_FILENAME
  • REQUEST_METHOD
  • REQUEST_SCHEME
  • REQUEST_URI
  • SCRIPT_FILENAME
  • SERVER_ADDR
  • SERVER_PORT
  • SERVER_PROTOCOL
  • TIME
  • TIME_DAY
  • TIME_HOUR
  • TIME_MIN
  • TIME_MON
  • TIME_SEC
  • TIME_WDAY
  • TIME_YEAR

IIS URL Yeniden Yazma Modülü kuralları

IIS URL Yeniden Yazma Modülü için geçerli olan aynı kural kümesini kullanmak için kullanın AddIISUrlRewrite. Kural dosyasının uygulamayla dağıtıldığından emin olun. Ara yazılımı Windows Server IIS'de çalışırken uygulamanın web.config dosyasını kullanmaya yönlendirmeyin. IIS ile, IIS Yeniden Yazma modülüyle çakışmaları önlemek için bu kurallar uygulamanın web.config dosyasının dışında depolanmalıdır. IIS URL Yeniden Yazma Modülü kuralları hakkında daha fazla bilgi ve örnek için bkz . Url Yeniden Yazma Modülü 2.0 kullanma ve URL Yeniden Yazma Modülü Yapılandırma Başvurusu.

, StreamReader kurallar dosyasından kuralları IISUrlRewrite.xml okumak için kullanılır:

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Örnek uygulama, 'den adresine /iis-rules-rewrite/(.*)/rewritten?id=$1istekleri yeniden yazar. Yanıt, istemciye 200 - Tamam durum koduyla gönderilir.

<rewrite>
  <rules>
    <rule name="Rewrite segment to id querystring" stopProcessing="true">
      <match url="^iis-rules-rewrite/(.*)$" />
      <action type="Rewrite" url="rewritten?id={R:1}" appendQueryString="false"/>
    </rule>
  </rules>
</rewrite>

Özgün İstek: /iis-rules-rewrite/1234

Browser window with developer tools tracking the request and response: Add IIS URL rewrite

Uygulamanızı istenmeyen şekillerde etkileyecek sunucu düzeyinde kurallar yapılandırılmış etkin bir IIS Yeniden Yazma Modülünüz varsa, bir uygulama için IIS Yeniden Yazma Modülünü devre dışı bırakabilirsiniz. Daha fazla bilgi için bkz . IIS modüllerini devre dışı bırakma.

Desteklenmeyen özellikler

Ara yazılım aşağıdaki IIS URL Yeniden Yazma Modülü özelliklerini desteklemez:

  • Giden Kuralları
  • Özel Sunucu Değişkenleri
  • Joker karakterler
  • LogRewrittenUrl

Desteklenen sunucu değişkenleri

Ara yazılım aşağıdaki IIS URL Yeniden Yazma Modülü sunucu değişkenlerini destekler:

  • CONTENT_LENGTH
  • CONTENT_TYPE
  • HTTP_ACCEPT
  • HTTP_CONNECTION
  • HTTP_COOKIE
  • HTTP_HOST
  • HTTP_REFERER
  • HTTP_URL
  • HTTP_USER_AGENT
  • HTTPS
  • LOCAL_ADDR
  • QUERY_STRING
  • REMOTE_ADDR
  • REMOTE_PORT
  • REQUEST_FILENAME
  • REQUEST_URI

Dekont

Ayrıca aracılığıyla da IFileProviderPhysicalFileProviderbir elde edebilirsiniz. Bu yaklaşım, yeniden yazma kuralları dosyalarınızın konumu için daha fazla esneklik sağlayabilir. Yeniden yazma kuralları dosyalarınızın sağladığınız yolda sunucuya dağıtıldığından emin olun.

PhysicalFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());

Yöntem tabanlı kural

Bir yöntemde kendi kural mantığınızı uygulamak için kullanın Add . AddRewriteContextyönteminizde kullanmak üzere öğesini kullanıma HttpContext sunan öğesini kullanıma sunar. RewriteContext.Result, ek işlem hattı işlemenin nasıl işleneceğini belirler. Değeri aşağıdaki tabloda açıklanan alanlardan birine RuleResult ayarlayın.

Bağlam sonucunu yeniden yazma Eylem
RuleResult.ContinueRules (varsayılan) Kuralları uygulamaya devam edin.
RuleResult.EndResponse Kuralları uygulamayı durdurun ve yanıtı gönderin.
RuleResult.SkipRemainingRules Kuralları uygulamayı durdurun ve bağlamı bir sonraki ara yazılıma gönderin.
public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Örnek uygulama, ile .xmlbiten yollar için istekleri yeniden yönlendiren bir yöntem gösterir. için /file.xmlbir istek yapılırsa, istek adresine /xmlfiles/file.xmlyönlendirilir. Durum kodu olarak 301 - Moved Permanentlyayarlanır. Tarayıcı için /xmlfiles/file.xmlyeni bir istek yaptığında, Statik Dosya Ara Yazılımı dosyayı wwwroot/xmlfiles klasöründen istemciye hizmet eder . Yeniden yönlendirme için yanıtın durum kodunu açıkça ayarlayın. Aksi takdirde, 200 - Tamam durum kodu döndürülür ve yeniden yönlendirme istemcide gerçekleşmez.

RewriteRules.cs:

public static void RedirectXmlFileRequests(RewriteContext context)
{
    var request = context.HttpContext.Request;

    // Because the client is redirecting back to the same app, stop 
    // processing if the request has already been redirected.
    if (request.Path.StartsWithSegments(new PathString("/xmlfiles")))
    {
        return;
    }

    if (request.Path.Value.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
    {
        var response = context.HttpContext.Response;
        response.StatusCode = (int) HttpStatusCode.MovedPermanently;
        context.Result = RuleResult.EndResponse;
        response.Headers[HeaderNames.Location] = 
            "/xmlfiles" + request.Path + request.QueryString;
    }
}

Bu yaklaşım istekleri de yeniden yazabilir. Örnek uygulama, wwwroot klasöründen file.txt metin dosyasını sunmak için herhangi bir metin dosyası isteğinin yolunu yeniden yazmayı gösterir. Statik Dosya Ara Yazılımı, güncelleştirilmiş istek yoluna göre dosyaya hizmet eder:

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

RewriteRules.cs:

public static void RewriteTextFileRequests(RewriteContext context)
{
    var request = context.HttpContext.Request;

    if (request.Path.Value.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
    {
        context.Result = RuleResult.SkipRemainingRules;
        request.Path = "/file.txt";
    }
}

IRule tabanlı kural

Arabirimini uygulayan IRule bir sınıfta kural mantığını kullanmak için kullanınAdd. IRule yöntem tabanlı kural yaklaşımını kullanma üzerinde daha fazla esneklik sağlar. Uygulama sınıfınız, yöntemi için ApplyRule parametreleri geçirebilmenizi sağlayan bir oluşturucu içerebilir.

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

ve newPath için örnek uygulamadaki extension parametrelerin değerleri çeşitli koşulları karşılamak için denetlenmektedir. extension bir değer içermeli ve değer , .jpgveya .gif olmalıdır.png. newPath geçerli değilse, bir ArgumentException oluşturulur. için image.pngbir istek yapılırsa, istek adresine /png-images/image.pngyönlendirilir. için image.jpgbir istek yapılırsa, istek adresine /jpg-images/image.jpgyönlendirilir. Durum kodu olarak 301 - Moved Permanentlyayarlanır ve context.Result kuralları işlemeyi durduracak ve yanıtı gönderecek şekilde ayarlanır.

public class RedirectImageRequests : IRule
{
    private readonly string _extension;
    private readonly PathString _newPath;

    public RedirectImageRequests(string extension, string newPath)
    {
        if (string.IsNullOrEmpty(extension))
        {
            throw new ArgumentException(nameof(extension));
        }

        if (!Regex.IsMatch(extension, @"^\.(png|jpg|gif)$"))
        {
            throw new ArgumentException("Invalid extension", nameof(extension));
        }

        if (!Regex.IsMatch(newPath, @"(/[A-Za-z0-9]+)+?"))
        {
            throw new ArgumentException("Invalid path", nameof(newPath));
        }

        _extension = extension;
        _newPath = new PathString(newPath);
    }

    public void ApplyRule(RewriteContext context)
    {
        var request = context.HttpContext.Request;

        // Because we're redirecting back to the same app, stop 
        // processing if the request has already been redirected
        if (request.Path.StartsWithSegments(new PathString(_newPath)))
        {
            return;
        }

        if (request.Path.Value.EndsWith(_extension, StringComparison.OrdinalIgnoreCase))
        {
            var response = context.HttpContext.Response;
            response.StatusCode = (int) HttpStatusCode.MovedPermanently;
            context.Result = RuleResult.EndResponse;
            response.Headers[HeaderNames.Location] = 
                _newPath + request.Path + request.QueryString;
        }
    }
}

Özgün İstek: /image.png

Browser window with developer tools tracking the requests and responses for image.png

Özgün İstek: /image.jpg

Browser window with developer tools tracking the requests and responses for image.jpg

Regex örnekleri

Goal Regex Dizesi &
Eşleşme Örneği
Değiştirme Dizesi &
Çıkış Örneği
Sorgu dizesine yolu yeniden yazma ^path/(.*)/(.*)
/path/abc/123
path?var1=$1&var2=$2
/path?var1=abc&var2=123
Şerit sondaki eğik çizgi (.*)/$
/path/
$1
/path
Sondaki eğik çizgiyi zorlama (.*[^/])$
/path
$1/
/path/
Belirli istekleri yeniden yazmaktan kaçının ^(.*)(?<!\.axd)$ veya ^(?!.*\.axd$)(.*)$
Evet: /resource.htm
No: /resource.axd
rewritten/$1
/rewritten/resource.htm
/resource.axd
URL kesimlerini yeniden düzenleme path/(.*)/(.*)/(.*)
path/1/2/3
path/$3/$2/$1
path/3/2/1
URL kesimini değiştirme ^(.*)/segment2/(.*)
/segment1/segment2/segment3
$1/replaced/$2
/segment1/replaced/segment3

Bu belgede, ASP.NET Core uygulamalarında URL Yeniden Yazma Ara Yazılımını kullanma yönergeleriyle birlikte URL yeniden yazma tanıtılması sağlanır.

URL yeniden yazma, önceden tanımlanmış bir veya daha fazla kurala göre istek URL'lerini değiştirme işlemidir. URL yeniden yazma, kaynak konumları ve adresleri arasında bir soyutlama oluşturur, böylece konumlar ve adresler sıkı bir şekilde bağlanmaz. URL yeniden yazma, çeşitli senaryolarda aşağıdakiler için değerlidir:

  • Sunucu kaynaklarını geçici veya kalıcı olarak taşıyın veya değiştirin ve bu kaynaklar için kararlı bulucuları koruyun.
  • farklı uygulamalar arasında veya bir uygulamanın alanları arasında bölünmüş istek işleme.
  • Gelen isteklerde URL kesimlerini kaldırın, ekleyin veya yeniden organize edin.
  • Arama Altyapısı İyileştirmesi (SEO) için genel URL'leri iyileştirin.
  • Ziyaretçilerin bir kaynak isteyerek döndürülen içeriği tahmin etmelerine yardımcı olmak için kolay genel URL'lerin kullanılmasına izin ver.
  • Güvenli olmayan istekleri güvenli uç noktalara yönlendirin.
  • Dış sitenin, varlığı kendi içeriğine bağlayarak başka bir sitede barındırılan statik varlığı kullandığı sık erişimli bağlantıyı engelleyin.

Dekont

URL yeniden yazma, bir uygulamanın performansını düşürebilir. Mümkün olduğunda kuralların sayısını ve karmaşıklığını sınırlayın.

Örnek kodu görüntüleme veya indirme (indirme)

URL yeniden yönlendirme ve URL yeniden yazma

URL yeniden yönlendirmesi ile URL yeniden yazma arasındaki ifade farkı incedir, ancak istemcilere kaynak sağlamaya yönelik önemli etkilere sahiptir. ASP.NET Core'un URL Yeniden Yazma Ara Yazılımı her iki gereksinimi de karşılayabildi.

URL yeniden yönlendirmesi, istemcinin başlangıçta istenenden farklı bir adresteki bir kaynağa erişmesi talimatının alındığı istemci tarafı işlemi içerir. Bunun için sunucuya gidiş dönüş gerekir. İstemci kaynak için yeni bir istekte bulunduğunda istemciye döndürülen yeniden yönlendirme URL'si tarayıcının adres çubuğunda görünür.

adresine yeniden yönlendirilirse/resource/different-resource, sunucu istemcinin kaynağı /different-resource adresinden alması gerektiğini ve yeniden yönlendirmenin geçici veya kalıcı olduğunu belirten bir durum koduyla yanıt verir.

A WebAPI service endpoint has been temporarily changed from version 1 (v1) to version 2 (v2) on the server. A client makes a request to the service at the version 1 path /v1/api. The server sends back a 302 (Found) response with the new, temporary path for the service at version 2 /v2/api. The client makes a second request to the service at the redirect URL. The server responds with a 200 (OK) status code.

İstekleri farklı bir URL'ye yeniden yönlendirirken, yanıtla birlikte durum kodunu belirterek yeniden yönlendirmenin kalıcı mı yoksa geçici mi olduğunu belirtin:

  • Durum 301 - Moved Permanently kodu, kaynağın yeni, kalıcı bir URL'ye sahip olduğu ve istemciye kaynak için gelecekteki tüm isteklerin yeni URL'yi kullanması gerektiğini bildirmek istediğiniz durumlarda kullanılır. İstemci, 301 durum kodu alındığında yanıtı önbelleğe alabilir ve yeniden kullanabilir.

  • Yeniden yönlendirmenin geçici olduğu veya genellikle değiştirilebilir olduğu 302 - Bulunan durum kodu kullanılır. 302 durum kodu, istemciye URL'yi depolamaması ve gelecekte kullanmaması için gösterir.

Durum kodları hakkında daha fazla bilgi için bkz . RFC 9110: Durum Kodu Tanımları.

URL yeniden yazma, istemcinin isteğinden farklı bir kaynak adresinden kaynak sağlayan sunucu tarafı bir işlemdir. URL'yi yeniden yazmak için sunucuya gidiş dönüş gerekmez. Yeniden yazılan URL istemciye döndürülmüyor ve tarayıcının adres çubuğunda görünmüyor.

için yeniden yazılırsa/resource, sunucu konumundaki kaynağı /different-resourcedahili olarak getirir ve döndürür./different-resource

İstemci, kaynağı yeniden yazılan URL'de alabilse de, istekte bulunduğunda ve yanıtı aldığında kaynağın yeniden yazılan URL'de mevcut olduğu bildirilmiyor.

A WebAPI service endpoint has been changed from version 1 (v1) to version 2 (v2) on the server. A client makes a request to the service at the version 1 path /v1/api. The request URL is rewritten to access the service at the version 2 path /v2/api. The service responds to the client with a 200 (OK) status code.

URL yeniden yazma örnek uygulaması

Örnek uygulamayla URL Yeniden Yazma Ara Yazılımının özelliklerini keşfedebilirsiniz. Uygulama yeniden yönlendirme ve yeniden yazma kuralları uygular ve çeşitli senaryolar için yeniden yönlendirilen veya yeniden yazılan URL'yi gösterir.

URL Yeniden Yazma Ara Yazılımı ne zaman kullanılır?

Aşağıdaki yaklaşımları kullanamıyorsanız URL Yeniden Yazma Ara Yazılımını kullanın:

Ayrıca, uygulama HTTP.sys sunucusunda (eski adı WebListener) barındırıldığında ara yazılımı kullanın.

IIS, Apache ve Nginx'te sunucu tabanlı URL yeniden yazma teknolojilerini kullanmanın başlıca nedenleri şunlardır:

  • Ara yazılım bu modüllerin tüm özelliklerini desteklemez.

    Sunucu modüllerinin bazı özellikleri, IIS Yeniden Yazma modülünün ve IsDirectory kısıtlamaları gibi IsFile ASP.NET Core projeleriyle çalışmaz. Bu senaryolarda bunun yerine ara yazılımı kullanın.

  • Ara yazılımların performansı büyük olasılıkla modüllerin performansıyla eşleşmiyordur.

    Kıyaslama, hangi yaklaşımın performansı en çok düşürüp düşürmediğini veya performansın düşürülmesinin göz ardı edilebilir olup olmadığını bilmenin tek yoludur.

Paket

Ara yazılımı projenize eklemek için, Microsoft.AspNetCore.Rewrite paketini içeren proje dosyasındaki Microsoft.AspNetCore.App meta paketine bir paket başvurusu ekleyin.

Meta paketi kullanmadığınızda Microsoft.AspNetCore.App pakete Microsoft.AspNetCore.Rewrite bir proje başvurusu ekleyin.

Uzantı ve seçenekler

Yeniden yazma kurallarınızın her biri için uzantı yöntemleriyle RewriteOptions sınıfının bir örneğini oluşturarak URL yeniden yazma ve yeniden yönlendirme kuralları oluşturun. Birden çok kuralı işlenmelerini istediğiniz sırayla zincirleyin. ile RewriteOptions istek işlem hattına UseRewritereklendikçe URL Yeniden Yazma Ara Yazılımına geçirilir:

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Www olmayanları www'ye yönlendirme

Üç seçenek, uygulamanın istek olmayanlarıwww uygulamasına yeniden yönlendirmesine wwwizin verir:

  • AddRedirectToWwwPermanent: İstek değilsewww isteği www kalıcı olarak alt etki alanına yeniden yönlendirin. Status308PermanentRedirect durum koduyla yeniden yönlendirir.

  • AddRedirectToWww: Gelen istek değilsewww isteği www alt etki alanına yeniden yönlendirin. Status307TemporaryRedirect durum koduyla yeniden yönlendirir. Aşırı yükleme, yanıt için durum kodunu sağlamanıza izin verir. Durum kodu ataması StatusCodes için sınıfının bir alanını kullanın.

URL yeniden yönlendirme

İstekleri yeniden yönlendirmek için kullanın AddRedirect . İlk parametre, gelen URL'nin yolunda eşleştirmek için regex'inizi içerir. İkinci parametre, değiştirme dizesidir. Varsa üçüncü parametre durum kodunu belirtir. Durum kodunu belirtmezseniz, durum kodu varsayılan olarak 302 - Bulundu olarak ayarlanır ve bu da kaynağın geçici olarak taşındığını veya değiştirildiğini gösterir.

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Geliştirici araçlarının etkinleştirildiği bir tarayıcıda, yolu /redirect-rule/1234/5678ile örnek uygulamaya bir istekte bulunabilirsiniz. Regex, üzerindeki redirect-rule/(.*)istek yoluyla eşleşir ve yolu ile /redirected/1234/5678değiştirilir. Yeniden yönlendirme URL'si 302 - Bulundu durum koduyla istemciye geri gönderilir. Tarayıcı, tarayıcının adres çubuğunda görünen yeniden yönlendirme URL'sinde yeni bir istekte bulunur. Örnek uygulamadaki hiçbir kural yeniden yönlendirme URL'sinde eşleşmediğinden:

  • İkinci istek, uygulamadan 200 - Tamam yanıtı alır.
  • Yanıtın gövdesi yeniden yönlendirme URL'sini gösterir.

URL yeniden yönlendirildiğinde sunucuya gidiş dönüş yapılır.

Uyarı

Yeniden yönlendirme kuralları oluştururken dikkatli olun. Yeniden yönlendirme kuralları, yeniden yönlendirmeden sonra da dahil olmak üzere uygulamaya yapılan her istekte değerlendirilir. Yanlışlıkla sonsuz yeniden yönlendirmeler döngüsü oluşturmak kolaydır.

Özgün İstek: /redirect-rule/1234/5678

Add redirect: Browser window with developer tools tracking the requests and responses

İfadenin parantez içinde yer alan bölümüne yakalama grubu adı verilir. İfadenin noktası (.) herhangi bir karakterle eşleşsin anlamına gelir. Yıldız işareti (*), önceki karakterle sıfır veya daha fazla kez eşleşdiğini gösterir. Bu nedenle, URL'nin son iki yol kesimi olan 1234/5678yakalama grubu (.*)tarafından yakalanır. İstek URL'sinde redirect-rule/ sağladığınız tüm değerler bu tek yakalama grubu tarafından yakalanır.

Değiştirilen dizede, yakalanan gruplar dizeye dolar işareti ($) ve ardından yakalamanın sıra numarası ile eklenir. İlk yakalama grubu değeri ile $1elde edilir, ikincisi ile elde $2edilir ve kayıt defterinizdeki yakalama grupları için sırayla devam eder. Örnek uygulamadaki yeniden yönlendirme kuralı reex'inde yalnızca bir yakalanan grup vardır, bu nedenle değiştirme dizesinde eklenen tek bir grup vardır; bu da olur $1. Kural uygulandığında URL olur /redirected/1234/5678.

URL güvenli bir uç noktaya yeniden yönlendirme

HTTPS protokolunu kullanarak HTTP isteklerini aynı ana bilgisayara ve yola yeniden yönlendirmek için kullanın AddRedirectToHttps . Durum kodu sağlanmazsa ara yazılım varsayılan olarak 302 - Bulundu olur. Bağlantı noktası sağlanmadıysa:

  • Ara yazılım varsayılan olarak olarak gösterilir null.
  • Düzen (HTTPS protokolü) olarak değişir https ve istemci 443 numaralı bağlantı noktasında kaynağa erişir.

Aşağıdaki örnekte durum kodunun 301 - Moved Permanently nasıl ayarlanacağı ve bağlantı noktasının 5001 olarak nasıl değiştireceği gösterilmektedir.

public void Configure(IApplicationBuilder app)
{
    var options = new RewriteOptions()
        .AddRedirectToHttps(301, 5001);

    app.UseRewriter(options);
}

Güvenli olmayan istekleri 443 numaralı bağlantı noktasında güvenli HTTPS protokolüyle aynı ana bilgisayara ve yola yönlendirmek için kullanın AddRedirectToHttpsPermanent . Ara yazılım durum kodunu olarak 301 - Moved Permanentlyayarlar.

public void Configure(IApplicationBuilder app)
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent();

    app.UseRewriter(options);
}

Dekont

Ek yeniden yönlendirme kuralları gerekmeden güvenli bir uç noktaya yeniden yönlendirme yaparken HTTPS Yeniden Yönlendirme Ara Yazılımı kullanmanızı öneririz. Daha fazla bilgi için HTTPS'yi zorunlu kılma konusuna bakın.

Örnek uygulama veya AddRedirectToHttpsPermanent'nin nasıl kullanılacağını AddRedirectToHttps gösterebilen bir uygulamadır. uzantısı yöntemini öğesine RewriteOptionsekleyin. Herhangi bir URL'de uygulamaya güvenli olmayan bir istekte bulunın. Otomatik olarak imzalanan sertifikaya güvenilmeyen tarayıcı güvenlik uyarısını kapatın veya sertifikaya güvenmek için bir özel durum oluşturun.

kullanarak AddRedirectToHttps(301, 5001)Özgün İstek: http://localhost:5000/secure

Add redirect to HTTPS: Browser window with developer tools tracking the requests and responses

kullanarak AddRedirectToHttpsPermanentÖzgün İstek: http://localhost:5000/secure

Add redirect to HTTPS permanent: Browser window with developer tools tracking the requests and responses

URL yeniden yazma

URL'leri yeniden yazmaya yönelik bir kural oluşturmak için kullanın AddRewrite . İlk parametre, gelen URL yolunda eşleştirme için regex'i içerir. İkinci parametre, değiştirme dizesidir. Üçüncü parametre, skipRemainingRules: {true|false}geçerli kural uygulanırsa ek yeniden yazma kurallarının atlanıp atlanmayacağını ara yazılıma gösterir.

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Özgün İstek: /rewrite-rule/1234/5678

Add rewrite: Browser window with developer tools tracking the request and response

İfadenin başındaki karat (^), eşleştirmenin URL yolunun başında başladığı anlamına gelir.

Önceki örnekte yeniden yönlendirme kuralıyla redirect-rule/(.*)birlikte, regex'in başında karat (^) yoktur. Bu nedenle, başarılı bir eşleşme için yolda herhangi bir karakter önce redirect-rule/ gelebilir.

Path Eşleştir
/redirect-rule/1234/5678 Evet
/my-cool-redirect-rule/1234/5678 Evet
/anotherredirect-rule/1234/5678 Evet

yeniden yazma kuralı, ^rewrite-rule/(\d+)/(\d+)yalnızca ile başlıyorsa yollarla rewrite-rule/eşleşir. Aşağıdaki tabloda, eşleştirme farkını not edin.

Path Eşleştir
/rewrite-rule/1234/5678 Evet
/my-cool-rewrite-rule/1234/5678 Hayı
/anotherrewrite-rule/1234/5678 Hayır

İfadenin ^rewrite-rule/ bölümünü takip eden iki yakalama grubu vardır: (\d+)/(\d+). İşaretler \dbir rakamla (sayı) eşleşir. Artı işareti (+), önceki karakterden biriyle veya daha fazlası ile eşleşen anlamına gelir. Bu nedenle, URL'nin bir sayı içermesi ve ardından eğik çizgi ve ardından başka bir sayı içermesi gerekir. Bu yakalama grupları, yeniden yazılan URL'ye ve $2olarak $1 eklenir. Yeniden yazma kuralı değiştirme dizesi, yakalanan grupları sorgu dizesine yerleştirir. kaynağı adresinden almak /rewritten?var1=1234&var2=5678için istenen yolu /rewrite-rule/1234/5678 yeniden yazılır. Özgün istekte bir sorgu dizesi varsa, URL yeniden yazıldığında korunur.

Kaynağı almak için sunucuya gidiş dönüş yoktur. Kaynak varsa, getirilir ve 200 - Tamam durum koduyla istemciye döndürülür. İstemci yeniden yönlendirilemediğinden, tarayıcının adres çubuğundaki URL değişmez. İstemciler sunucuda url yeniden yazma işleminin gerçekleştiğini algılayamaz.

Dekont

Eşleştirme kuralları hesaplama açısından pahalı olduğundan ve uygulama yanıt süresini artırdığından mümkün olduğunca kullanın skipRemainingRules: true . En hızlı uygulama yanıtı için:

  • En sık eşleşen kuraldan en az eşleşen kurala yeniden yazma kurallarını sırala.
  • Bir eşleşme oluştuğunda ve ek kural işleme gerekli olmadığında kalan kuralların işlenmesini atlayın.

Apache mod_rewrite

ile AddApacheModRewriteApache mod_rewrite kuralları uygulama. Kural dosyasının uygulamayla dağıtıldığından emin olun. mod_rewrite kuralları hakkında daha fazla bilgi ve örnek için bkz . Apache mod_rewrite.

, StreamReader ApacheModRewrite.txt kural dosyasındaki kuralları okumak için kullanılır:

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Örnek uygulama, 'den /apache-mod-rules-redirect/(.\*) istekleri'ne /redirected?id=$1yönlendirir. Yanıt durum kodu : 302 - Bulundu.

# Rewrite path with additional sub directory
RewriteRule ^/apache-mod-rules-redirect/(.*) /redirected?id=$1 [L,R=302]

Özgün İstek: /apache-mod-rules-redirect/1234

Add Apache mod redirect: Browser window with developer tools tracking the requests and responses

Ara yazılım aşağıdaki Apache mod_rewrite sunucu değişkenlerini destekler:

  • CONN_REMOTE_ADDR
  • HTTP_ACCEPT
  • HTTP_CONNECTION
  • HTTP_COOKIE
  • HTTP_FORWARDED
  • HTTP_HOST
  • HTTP_REFERER
  • HTTP_USER_AGENT
  • HTTPS
  • IPV6
  • QUERY_STRING
  • REMOTE_ADDR
  • REMOTE_PORT
  • REQUEST_FILENAME
  • REQUEST_METHOD
  • REQUEST_SCHEME
  • REQUEST_URI
  • SCRIPT_FILENAME
  • SERVER_ADDR
  • SERVER_PORT
  • SERVER_PROTOCOL
  • TIME
  • TIME_DAY
  • TIME_HOUR
  • TIME_MIN
  • TIME_MON
  • TIME_SEC
  • TIME_WDAY
  • TIME_YEAR

IIS URL Yeniden Yazma Modülü kuralları

IIS URL Yeniden Yazma Modülü için geçerli olan aynı kural kümesini kullanmak için kullanın AddIISUrlRewrite. Kural dosyasının uygulamayla dağıtıldığından emin olun. Ara yazılımı Windows Server IIS'de çalışırken uygulamanın web.config dosyasını kullanmaya yönlendirmeyin. IIS ile, IIS Yeniden Yazma modülüyle çakışmaları önlemek için bu kurallar uygulamanın web.config dosyasının dışında depolanmalıdır. IIS URL Yeniden Yazma Modülü kuralları hakkında daha fazla bilgi ve örnek için bkz . Url Yeniden Yazma Modülü 2.0 kullanma ve URL Yeniden Yazma Modülü Yapılandırma Başvurusu.

, StreamReader kurallar dosyasından kuralları IISUrlRewrite.xml okumak için kullanılır:

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Örnek uygulama, 'den adresine /iis-rules-rewrite/(.*)/rewritten?id=$1istekleri yeniden yazar. Yanıt, istemciye 200 - Tamam durum koduyla gönderilir.

<rewrite>
  <rules>
    <rule name="Rewrite segment to id querystring" stopProcessing="true">
      <match url="^iis-rules-rewrite/(.*)$" />
      <action type="Rewrite" url="rewritten?id={R:1}" appendQueryString="false"/>
    </rule>
  </rules>
</rewrite>

Özgün İstek: /iis-rules-rewrite/1234

Add IIS URL rewrite: Browser window with developer tools tracking the request and response

Uygulamanızı istenmeyen şekillerde etkileyecek sunucu düzeyinde kurallar yapılandırılmış etkin bir IIS Yeniden Yazma Modülünüz varsa, bir uygulama için IIS Yeniden Yazma Modülünü devre dışı bırakabilirsiniz. Daha fazla bilgi için bkz . IIS modüllerini devre dışı bırakma.

Desteklenmeyen özellikler

ASP.NET Core 2.x ile yayımlanan ara yazılım, aşağıdaki IIS URL Yeniden Yazma Modülü özelliklerini desteklemez:

  • Giden Kuralları
  • Özel Sunucu Değişkenleri
  • Joker karakterler
  • LogRewrittenUrl

Desteklenen sunucu değişkenleri

Ara yazılım aşağıdaki IIS URL Yeniden Yazma Modülü sunucu değişkenlerini destekler:

  • CONTENT_LENGTH
  • CONTENT_TYPE
  • HTTP_ACCEPT
  • HTTP_CONNECTION
  • HTTP_COOKIE
  • HTTP_HOST
  • HTTP_REFERER
  • HTTP_URL
  • HTTP_USER_AGENT
  • HTTPS
  • LOCAL_ADDR
  • QUERY_STRING
  • REMOTE_ADDR
  • REMOTE_PORT
  • REQUEST_FILENAME
  • REQUEST_URI

Dekont

Ayrıca aracılığıyla da IFileProviderPhysicalFileProviderbir elde edebilirsiniz. Bu yaklaşım, yeniden yazma kuralları dosyalarınızın konumu için daha fazla esneklik sağlayabilir. Yeniden yazma kuralları dosyalarınızın sağladığınız yolda sunucuya dağıtıldığından emin olun.

PhysicalFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());

Yöntem tabanlı kural

Bir yöntemde kendi kural mantığınızı uygulamak için kullanın Add . AddRewriteContextyönteminizde kullanmak üzere öğesini kullanıma HttpContext sunan öğesini kullanıma sunar. RewriteContext.Result, ek işlem hattı işlemenin nasıl işleneceğini belirler. Değeri aşağıdaki tabloda açıklanan alanlardan birine RuleResult ayarlayın.

Bağlam sonucunu yeniden yazma Eylem
RuleResult.ContinueRules (varsayılan) Kuralları uygulamaya devam edin.
RuleResult.EndResponse Kuralları uygulamayı durdurun ve yanıtı gönderin.
RuleResult.SkipRemainingRules Kuralları uygulamayı durdurun ve bağlamı bir sonraki ara yazılıma gönderin.
public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Örnek uygulama, ile .xmlbiten yollar için istekleri yeniden yönlendiren bir yöntem gösterir. için /file.xmlbir istek yapılırsa, istek adresine /xmlfiles/file.xmlyönlendirilir. Durum kodu olarak 301 - Moved Permanentlyayarlanır. Tarayıcı için /xmlfiles/file.xmlyeni bir istek yaptığında, Statik Dosya Ara Yazılımı dosyayı wwwroot/xmlfiles klasöründen istemciye hizmet eder . Yeniden yönlendirme için yanıtın durum kodunu açıkça ayarlayın. Aksi takdirde, 200 - Tamam durum kodu döndürülür ve yeniden yönlendirme istemcide gerçekleşmez.

RewriteRules.cs:

public static void RedirectXmlFileRequests(RewriteContext context)
{
    var request = context.HttpContext.Request;

    // Because the client is redirecting back to the same app, stop 
    // processing if the request has already been redirected.
    if (request.Path.StartsWithSegments(new PathString("/xmlfiles")))
    {
        return;
    }

    if (request.Path.Value.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
    {
        var response = context.HttpContext.Response;
        response.StatusCode = (int) HttpStatusCode.MovedPermanently;
        context.Result = RuleResult.EndResponse;
        response.Headers[HeaderNames.Location] = 
            "/xmlfiles" + request.Path + request.QueryString;
    }
}

Bu yaklaşım istekleri de yeniden yazabilir. Örnek uygulama, wwwroot klasöründen file.txt metin dosyasını sunmak için herhangi bir metin dosyası isteğinin yolunu yeniden yazmayı gösterir. Statik Dosya Ara Yazılımı, güncelleştirilmiş istek yoluna göre dosyaya hizmet eder:

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

RewriteRules.cs:

public static void RewriteTextFileRequests(RewriteContext context)
{
    var request = context.HttpContext.Request;

    if (request.Path.Value.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
    {
        context.Result = RuleResult.SkipRemainingRules;
        request.Path = "/file.txt";
    }
}

IRule tabanlı kural

Arabirimini uygulayan IRule bir sınıfta kural mantığını kullanmak için kullanınAdd. IRule yöntem tabanlı kural yaklaşımını kullanma üzerinde daha fazla esneklik sağlar. Uygulama sınıfınız, yöntemi için ApplyRule parametreleri geçirebilmenizi sağlayan bir oluşturucu içerebilir.

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

ve newPath için örnek uygulamadaki extension parametrelerin değerleri çeşitli koşulları karşılamak için denetlenmektedir. extension bir değer içermeli ve değer , .jpgveya .gif olmalıdır.png. newPath geçerli değilse, bir ArgumentException oluşturulur. için image.pngbir istek yapılırsa, istek adresine /png-images/image.pngyönlendirilir. için image.jpgbir istek yapılırsa, istek adresine /jpg-images/image.jpgyönlendirilir. Durum kodu olarak 301 - Moved Permanentlyayarlanır ve context.Result kuralları işlemeyi durduracak ve yanıtı gönderecek şekilde ayarlanır.

public class RedirectImageRequests : IRule
{
    private readonly string _extension;
    private readonly PathString _newPath;

    public RedirectImageRequests(string extension, string newPath)
    {
        if (string.IsNullOrEmpty(extension))
        {
            throw new ArgumentException(nameof(extension));
        }

        if (!Regex.IsMatch(extension, @"^\.(png|jpg|gif)$"))
        {
            throw new ArgumentException("Invalid extension", nameof(extension));
        }

        if (!Regex.IsMatch(newPath, @"(/[A-Za-z0-9]+)+?"))
        {
            throw new ArgumentException("Invalid path", nameof(newPath));
        }

        _extension = extension;
        _newPath = new PathString(newPath);
    }

    public void ApplyRule(RewriteContext context)
    {
        var request = context.HttpContext.Request;

        // Because we're redirecting back to the same app, stop 
        // processing if the request has already been redirected
        if (request.Path.StartsWithSegments(new PathString(_newPath)))
        {
            return;
        }

        if (request.Path.Value.EndsWith(_extension, StringComparison.OrdinalIgnoreCase))
        {
            var response = context.HttpContext.Response;
            response.StatusCode = (int) HttpStatusCode.MovedPermanently;
            context.Result = RuleResult.EndResponse;
            response.Headers[HeaderNames.Location] = 
                _newPath + request.Path + request.QueryString;
        }
    }
}

Özgün İstek: /image.png

For image.png: Browser window with developer tools tracking the requests and responses

Özgün İstek: /image.jpg

For image.jpg: Browser window with developer tools tracking the requests and responses

Regex örnekleri

Goal Regex Dizesi &
Eşleşme Örneği
Değiştirme Dizesi &
Çıkış Örneği
Sorgu dizesine yolu yeniden yazma ^path/(.*)/(.*)
/path/abc/123
path?var1=$1&var2=$2
/path?var1=abc&var2=123
Şerit sondaki eğik çizgi (.*)/$
/path/
$1
/path
Sondaki eğik çizgiyi zorlama (.*[^/])$
/path
$1/
/path/
Belirli istekleri yeniden yazmaktan kaçının ^(.*)(?<!\.axd)$ veya ^(?!.*\.axd$)(.*)$
Evet: /resource.htm
No: /resource.axd
rewritten/$1
/rewritten/resource.htm
/resource.axd
URL kesimlerini yeniden düzenleme path/(.*)/(.*)/(.*)
path/1/2/3
path/$3/$2/$1
path/3/2/1
URL kesimini değiştirme ^(.*)/segment2/(.*)
/segment1/segment2/segment3
$1/replaced/$2
/segment1/replaced/segment3

Ek kaynaklar