Middleware pro přepis adres URL v ASP.NET Core
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v zásadách podpory .NET a .NET Core. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Tento článek představuje přepis adres URL s pokyny k použití middlewaru pro přepis adres URL v aplikacích ASP.NET Core.
Přepsání adresy URL je úprava adres URL požadavků na základě jednoho nebo více předdefinovaných pravidel. Přepsání adresy URL vytvoří abstrakci mezi umístěními prostředků a jejich adresami, takže umístění a adresy nejsou úzce propojené. Přepsání adresy URL je cenné v několika scénářích pro:
- Přesuňte nebo nahraďte prostředky serveru dočasně nebo trvale a udržujte stabilní lokátory těchto prostředků.
- Rozdělte zpracování žádostí mezi různé aplikace nebo napříč oblastmi jedné aplikace.
- Odeberte, přidejte nebo reorganizujte segmenty adres URL u příchozích požadavků.
- Optimalizace veřejných adres URL pro optimalizaci vyhledávacích webů (SEO).
- Povolte použití přátelských veřejných adres URL, které návštěvníkům pomůžou předpovědět obsah vrácený žádostí o prostředek.
- Přesměrujte nezabezpečené požadavky na zabezpečené koncové body.
- Znemožnit propojení s hotlinkingem, kdy externí web používá hostovaný statický prostředek na jiném webu propojením prostředku s vlastním obsahem.
Přepsání adresy URL může snížit výkon aplikace. Omezte počet a složitost pravidel.
Přesměrování adresy URL a přepsání adresy URL
Rozdíl ve formulaci přesměrování adresy URL a přepsání adresy URL je malý, ale má důležité důsledky pro poskytování prostředků klientům. ASP.NET middlewaru pro přepis adresy URL jádra je schopen splnit potřebu obojího.
Přesměrování adresy URL zahrnuje operaci na straně klienta, kde se klientovi dá pokyn, aby přistupoval k prostředku na jiné adrese než původně požadovaný klient. To vyžaduje odezvu na server. Adresa URL přesměrování vrácená klientovi se zobrazí v adresní řádku prohlížeče, když klient provede nový požadavek na prostředek.
Pokud /resource
je přesměrování na /different-resource
server, server odpoví, že klient by měl získat prostředek se /different-resource
stavovým kódem označujícím, že přesměrování je dočasné nebo trvalé.
Při přesměrování požadavků na jinou adresu URL určete, jestli je přesměrování trvalé nebo dočasné, zadáním stavového kódu s odpovědí:
301 - Moved Permanently
Stavový kód se používá, pokud má prostředek novou, trvalou adresu URL a že všechny budoucí požadavky na prostředek by měly používat novou adresu URL. Klient může ukládat odpověď do mezipaměti a opakovaně používat při přijetí stavového kódu 301.Stavový
302 - Found
kód se používá, pokud je přesměrování dočasné nebo obecně se může změnit. Stavový kód 302 označuje klientovi, aby neukládal adresu URL a v budoucnu ji používal.
Další informace o stavových kódech najdete v dokumentu RFC 9110: Definice stavových kódů.
Přepsání adresy URL je operace na straně serveru, která poskytuje prostředek z jiné adresy prostředku, než si klient vyžádal. Přepsání adresy URL nevyžaduje odezvu na server. Přepsaná adresa URL se klientovi nevrátí a nezobrazuje se v adresním řádku prohlížeče.
Pokud /resource
se přepíše , /different-resource
server interně načte a vrátí prostředek na adrese /different-resource
.
I když klient může být schopen načíst prostředek na přepsané adrese URL, klient není informován, že prostředek existuje na přepsané adrese URL, když odešle požadavek a obdrží odpověď.
Ukázková aplikace pro přepis adres URL
Prozkoumejte funkce middlewaru pro přepis adres URL pomocí ukázkové aplikace. Aplikace použije pravidla přesměrování a přepsání a zobrazí přesměrovanou nebo přepsanou adresu URL pro několik scénářů.
Kdy použít middleware pro přepis adres URL
Pokud následující přístupy nevyhovují, použijte middleware pro přepis adres URL:
- Modul přepsání adresy URL službou IIS na Windows Serveru
- Modul Apache mod_rewrite na Apache Serveru
- Přepsání adresy URL ve službě Nginx
Při hostování aplikace na HTTP.sys serveru použijte middleware pro přepis adres URL.
Hlavními důvody použití technologií přepisování adres URL na serveru ve službě IIS, Apache a Nginx jsou:
Middleware nepodporuje úplné funkce těchto modulů.
Některé funkce modulů serveru nefungují s projekty ASP.NET Core, jako
IsFile
jsou například omezení modulu přepisování služby IIS aIsDirectory
omezení. V těchto scénářích místo toho použijte middleware.Výkon middlewaru pravděpodobně neodpovídá výkonu modulů.
Srovnávací testy jsou jediným způsobem, jak zjistit jistotu, který přístup snižuje výkon nejvíce nebo pokud je snížený výkon zanedbatelný.
Rozšíření a možnosti
Vytvořte pravidla přepsání adresy URL a přesměrování vytvořením instance třídy RewriteOptions s rozšiřujícími metodami pro každou pravidla přepsání. Zřetězte více pravidel v pořadí, v jakém se mají zpracovat. Předávají RewriteOptions
se do middlewaru pro přepis adresy URL při přidání do kanálu požadavku:UseRewriter
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();
V předchozím kódu MethodRules
je uživatelsky definovaná třída. Další informace najdete RewriteRules.cs
v tomto článku.
Přesměrovat jiné než www na www
Tři možnosti umožňují aplikaci přesměrovat požadavky,www
na www
které nejsou požadavky:
AddRedirectToWwwPermanent: Trvale přesměrujte požadavek na subdoménu
www
, pokud požadavek neníwww
. Přesměruje se stavovým kódem Status308PermanentRedirect .AddRedirectToWww: Přesměrujte požadavek na subdoménu
www
, pokud příchozí požadavek neníwww
. Přesměruje se stavovým kódem Status307TemporaryRedirect . Přetížení umožňuje poskytnutí stavového kódu pro odpověď. Pro přiřazení stavového kódu použijte pole StatusCodes třídy.
Přesměrování adresy URL
Slouží AddRedirect k přesměrování požadavků. První parametr obsahuje regulární výraz .NET (Regex) pro porovnávání na cestě příchozí adresy URL. Druhým parametrem je náhradní řetězec. Třetí parametr, pokud je k dispozici, určuje stavový kód. Pokud není zadaný stavový kód, výchozí stavový kód je 302 – Nalezeno, což znamená, že se prostředek dočasně přesune nebo nahradí.
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();
V prohlížeči s povolenými vývojářskými nástroji vytvořte požadavek na ukázkovou aplikaci s cestou /redirect-rule/1234/5678
. Regulární výraz odpovídá cestě požadavku na redirect-rule/(.*)
a cesta je nahrazena /redirected/1234/5678
. Adresa URL přesměrování se odešle zpět klientovi se stavovým kódem 302. Prohlížeč vytvoří nový požadavek na adresu URL přesměrování, která se zobrazí v adresní řádku prohlížeče. Vzhledem k tomu, že se žádná pravidla v ukázkové aplikaci neshoduje s adresou URL pro přesměrování:
- Druhý požadavek obdrží odpověď 200 – OK z aplikace.
- Text odpovědi zobrazuje adresu URL pro přesměrování.
Při přesměrování adresy URL se na server provede odezva.
Upozorňující
Při vytváření pravidel přesměrování buďte opatrní. Pravidla přesměrování se vyhodnocují při každém požadavku na aplikaci, včetně po přesměrování. Náhodné vytvoření smyčky nekonečných přesměrování je snadné.
Část výrazu obsaženého v závorkách se nazývá skupina zachycení. Tečka (.
) výrazu odpovídá libovolnému znaku. Hvězdička (*
) označuje shodu s předchozím znakem nula nebo vícekrát. Proto jsou poslední dva segmenty cesty adresy URL zachyceny 1234/5678
skupinou (.*)
zachycení . Jakákoli hodnota zadaná v adrese URL požadavku po redirect-rule/
zachycení touto jednou skupinou zachycení.
V náhradním řetězci se zachycené skupiny vloží do řetězce se znaménkem dolaru ($
) následovaným pořadovým číslem zachycení. První hodnota skupiny zachycení je získána s $1
, druhý s $2
a pokračuje v sekvenci pro skupiny zachycení v regulárním výrazu. V regulárním výrazu redirect-rule/(.*)
pravidla přesměrování existuje pouze jedna zachycená skupina, takže v náhradním řetězci existuje pouze jedna vložená skupina, což je $1
. Při použití pravidla se adresa URL stane /redirected/1234/5678
.
Zkuste použít /redirect-rule/1234/5678
nástroje prohlížeče na kartě Síť.
Přesměrování adresy URL na zabezpečený koncový bod
Slouží AddRedirectToHttps k přesměrování požadavků HTTP na stejného hostitele a cestu pomocí protokolu HTTPS. Pokud stavový kód není zadaný, middleware se ve výchozím nastavení nastaví na hodnotu 302 – Nalezeno. Pokud port není zadaný:
- Ve výchozím nastavení se middleware nastaví na
null
. - Schéma se změní na
https
protokol HTTPS a klient přistupuje k prostředku na portu 443.
Následující příklad ukazuje, jak nastavit stavový kód na 301 - Moved Permanently
port HTTPS používaný Kestrel na místním hostiteli a změnit ho na port HTTPS. V produkčním prostředí je port HTTPS nastavený na hodnotu null:
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();
Slouží AddRedirectToHttpsPermanent k přesměrování nezabezpečených požadavků na stejného hostitele a cestu se zabezpečeným protokolem HTTPS na portu 443. Middleware nastaví stavový kód na 301 - Moved Permanently
.
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();
Poznámka:
Při přesměrování na zabezpečený koncový bod bez požadavku na další pravidla přesměrování doporučujeme použít middleware přesměrování HTTPS. Další informace najdete v tématu Vynucení HTTPS.
Ukázková aplikace ukazuje, jak používat AddRedirectToHttps
nebo AddRedirectToHttpsPermanent
. Zabezpečte požadavek HTTP na aplikaci na adrese http://redirect6.azurewebsites.net/iis-rules-rewrite/xyz
. Při testování přesměrování HTTP na HTTPS pomocí místního hostitele:
- Použijte adresu URL HTTP, která má jiný port než adresa URL HTTPS. Adresa URL PROTOKOLU HTTP je v
Properties/launchSettings.json
souboru. s
Odebrání zhttps://localhost/{port}
důvodu selhání kvůli tomu, že localhost nereaguje na port HTTPS na http.
Následující obrázek ukazuje obrázek nástrojů prohlížeče F12 požadavku na http://redirect6.azurewebsites.net/iis-rules-rewrite/xyz
použití předchozího kódu:
Přepsání adresy URL
Slouží AddRewrite k vytvoření pravidla pro přepis adres URL. První parametr obsahuje regulární výraz pro porovnávání v cestě příchozí adresy URL. Druhým parametrem je náhradní řetězec. Třetí parametr , skipRemainingRules: {true|false}
označuje middleware zda přeskočit další přepis pravidla, pokud je aktuální pravidlo použito.
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();
Zkuste požadavek na https://redirect6.azurewebsites.net/rewrite-rule/1234/5678
Stříška (^
) na začátku výrazu znamená, že porovnávání začíná na začátku cesty URL.
V předchozím příkladu s pravidlem redirect-rule/(.*)
přesměrování neexistuje žádná stříška (^
) na začátku regulárního výrazu. Proto všechny znaky mohou předcházet redirect-rule/
v cestě pro úspěšnou shodu.
Cesta | Párování |
---|---|
/redirect-rule/1234/5678 |
Ano |
/my-cool-redirect-rule/1234/5678 |
Ano |
/anotherredirect-rule/1234/5678 |
Yes |
Pravidlo přepsání odpovídá ^rewrite-rule/(\d+)/(\d+)
pouze cestám, pokud začínají rewrite-rule/
na . V následující tabulce si všimněte rozdílu ve shodě.
Cesta | Párování |
---|---|
/rewrite-rule/1234/5678 |
Yes |
/my-cool-rewrite-rule/1234/5678 |
No |
/anotherrewrite-rule/1234/5678 |
Ne |
^rewrite-rule/
Za částí výrazu jsou dvě skupiny zachycení , (\d+)/(\d+)
. Symboly \d
odpovídají číslici (číslo). Znaménko plus (+
) znamená shodu s jedním nebo více předchozím znakem. Proto musí adresa URL obsahovat číslo následované lomítkem následovaným jiným číslem. Tyto skupiny zachycení se vloží do přepsané adresy URL jako $1
a $2
. Řetězec nahrazení pravidla přepsáním umístí zachycené skupiny do řetězce dotazu. Požadovaná cesta /rewrite-rule/1234/5678
se přepíše tak, aby vrátila prostředek na adrese /rewritten?var1=1234&var2=5678
. Pokud v původním požadavku existuje řetězec dotazu, zachová se při přepsání adresy URL.
Na server neexistuje žádná zpáteční cesta, která by vrátila prostředek. Pokud prostředek existuje, načte se a vrátí klientovi se stavovým kódem 200 – OK . Vzhledem k tomu, že klient není přesměrován, adresa URL v adresní řádku prohlížeče se nezmění. Klienti nemůžou zjistit, že na serveru došlo k operaci přepsání adresy URL.
Tipy pro zvýšení výkonu pro přepsání a přesměrování adres URL
Nejrychlejší odpověď:
- Pravidla přepisování objednávek z nejčastěji vyhovujícího pravidla na pravidlo, které odpovídá nejméně často.
- Kdykoli
skipRemainingRules: true
je to možné, protože odpovídající pravidla jsou výpočetně náročná a zvyšují dobu odezvy aplikace. Přeskočte zpracování zbývajících pravidel, když dojde ke shodě, a nevyžaduje se žádné další zpracování pravidel.
Upozorňující
Uživatel se zlými úmysly může poskytnout nákladné zpracování vstupu, aby způsoboval RegularExpressions
útok na dostupnost služby. ASP.NET rozhraní API architektury Core, která používají RegularExpressions
vypršení časového limitu. Například třídy RedirectRule a RewriteRule předávají do jednoho druhého časového limitu.
Apache mod_rewrite
Použití pravidel Apache mod_rewrite s AddApacheModRewrite. Ujistěte se, že je soubor pravidel nasazený s aplikací. Další informace a příklady pravidel mod_rewrite najdete v tématu Apache mod_rewrite.
A StreamReader slouží ke čtení pravidel ze souboru pravidel ApacheModRewrite.txt :
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();
Ukázková aplikace přesměruje požadavky z /apache-mod-rules-redirect/(.\*)
./redirected?id=$1
Stavový kód odpovědi je 302 – Nalezeno.
# Rewrite path with additional sub directory
RewriteRule ^/apache-mod-rules-redirect/(.*) /redirected?id=$1 [L,R=302]
Zkuste požadavek na https://redirect6.azurewebsites.net/apache-mod-rules-redirect/1234
Middleware Apache podporuje následující proměnné serveru Apache mod_rewrite:
- 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
Pravidla modulu přepsání adresy URL služby IIS
Chcete-li použít stejnou sadu pravidel, která se vztahuje na modul přepsání adresy URL služby IIS, použijte AddIISUrlRewrite. Ujistěte se, že je soubor pravidel nasazený s aplikací. Nesměrujte middleware tak, aby při spuštění ve službě Windows Server IIS používal soubor web.config aplikace. U služby IIS by tato pravidla měla být uložena mimo soubor web.config aplikace, aby nedocházelo ke konfliktům s modulem iis Rewrite. Další informace a příklady pravidel modulu přepsání adresy URL služby IIS naleznete v tématu Použití modulu přepsání adresy URL 2.0 a odkazy na konfiguraci modulu přepisu adresy URL.
A StreamReader slouží ke čtení pravidel ze IISUrlRewrite.xml
souboru pravidel:
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();
Ukázková aplikace přepisuje požadavky z /iis-rules-rewrite/(.*)
do /rewritten?id=$1
. Odpověď se odešle klientovi se stavovým kódem 200 – OK .
<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>
Zkuste požadavek na https://redirect6.azurewebsites.net/iis-rules-rewrite/xyz
Aplikace, které mají aktivní modul pro přepis služby IIS s nakonfigurovanými pravidly na úrovni serveru, která ovlivňují aplikaci nežádoucími způsoby:
- Zvažte zakázání modulu pro přepsání služby IIS pro aplikaci.
- Další informace naleznete v tématu Zakázání modulů služby IIS.
Nepodporované funkce
Middleware nepodporuje následující funkce modulu přepsání adresy URL služby IIS:
- Pravidla pro odchozí provoz
- Vlastní proměnné serveru
- Zástupné znaky
- LogRewrittenUrl
Podporované proměnné serveru
Middleware podporuje následující proměnné serveru modulu pro přepsání adresy URL služby IIS:
- 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 lze získat prostřednictvím PhysicalFileProvider. Tento přístup může poskytovat větší flexibilitu pro umístění souborů pravidel přepsání. Ujistěte se, že jsou soubory pravidel přepsání nasazené na server v zadané cestě.
var fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());
Pravidlo založené na metodách
Slouží Add k implementaci vlastní logiky pravidla v metodě. Add
RewriteContextzveřejňuje , který zpřístupňuje HttpContext pro použití v metodách přesměrování. Vlastnost RewriteContext.Result určuje, jak se zpracovává další zpracování kanálu. Nastavte hodnotu na jedno z RuleResult polí popsaných v následující tabulce.
Přepsat výsledek kontextu | Akce |
---|---|
RuleResult.ContinueRules (výchozí) |
Pokračujte v používání pravidel. |
RuleResult.EndResponse |
Ukončete použití pravidel a odešlete odpověď. |
RuleResult.SkipRemainingRules |
Ukončete použití pravidel a odešlete kontext do dalšího middlewaru. |
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();
Ukázková aplikace ukazuje metodu, která přesměruje požadavky na cesty, které končí .xml
. Při provedení žádosti o /file.xml
:
- Požadavek se přesměruje na
/xmlfiles/file.xml
- Stavový kód je nastaven na
301 - Moved Permanently
hodnotu . Když prohlížeč vytvoří nový požadavek na/xmlfiles/file.xml
, statický soubor Middleware obsluhuje soubor klientovi ze složky wwwroot/xmlfiles . Pro přesměrování explicitně nastavte stavový kód odpovědi. V opačném případě se vrátí stavový kód 200 – OK a v klientovi nedojde k přesměrování.
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;
}
}
Tento přístup může také přepsat požadavky. Ukázková aplikace ukazuje přepsání cesty pro jakýkoli požadavek na textový soubor, který bude sloužit file.txt textovému souboru ze složky wwwroot. Middleware statického souboru slouží k souboru na základě aktualizované cesty požadavku:
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";
}
}
Pravidlo založené na IRule
Používá Add se k použití logiky pravidla ve třídě, která implementuje IRule rozhraní. IRule
poskytuje větší flexibilitu při používání přístupu založeného na metodách. Třída implementace může obsahovat konstruktor, který umožňuje předávání parametrů pro metodu ApplyRule .
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();
Hodnoty parametrů v ukázkové aplikaci a extension
jsou newPath
kontrolovány tak, aby splňovaly několik podmínek. Musí extension
obsahovat hodnotu a hodnota musí být .png
, .jpg
nebo .gif
. newPath
Pokud není platný, vyvolá se chybaArgumentException. Pokud je žádost podána image.png
, žádost se přesměruje na /png-images/image.png
. Pokud je žádost podána image.jpg
, žádost se přesměruje na /jpg-images/image.jpg
. Stavový kód je nastaven na hodnotu a context.Result
je nastaven na 301 - Moved Permanently
zastavení zpracování pravidel a odeslání odpovědi.
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;
}
}
}
Vyzkoušejte:
- Požadavek PNG:
https://redirect6.azurewebsites.net/image.png
- Žádost JPG:
https://redirect6.azurewebsites.net/image.jpg
Příklady regulárních výrazů
Goal | Řetězec regulárního výrazu a Příklad shody |
Náhradní řetězec &. Příklad výstupu |
---|---|---|
Přepsání cesty do řetězce dotazu | ^path/(.*)/(.*) /path/abc/123 |
path?var1=$1&var2=$2 /path?var1=abc&var2=123 |
Pruh koncové lomítko | ^path2/(.*)/$ /path2/xyz/ |
$1 /path2/xyz |
Vynucení koncového lomítka | ^path3/(.*[^/])$ /path3/xyz |
$1/ /path3/xyz/ |
Vyhněte se přepisování konkrétních požadavků | ^(.*)(?<!\.axd)$ nebo ^(?!.*\.axd$)(.*)$ Ano: /path4/resource.htm Ne: /path4/resource.axd |
rewritten/$1 /rewritten/resource.htm /resource.axd |
Změna uspořádání segmentů adres URL | path5/(.*)/(.*)/(.*) path5/1/2/3 |
path5/$3/$2/$1 path5/3/2/1 |
Nahrazení segmentu adresy URL | ^path6/(.*)/segment2/(.*) ^path6/segment1/segment2/segment3 |
path6/$1/replaced/$2 /path6/segment1/replaced/segment3 |
Odkazy v předchozí tabulce používají následující kód nasazený do Azure:
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();
Ve většině předchozích ukázek regulárních výrazů se literál path
používá k vytvoření jedinečných testovatelných pravidel přepisování nasazené ukázky. Regulární výraz obvykle neobsahuje path
. Podívejte se například na tabulku s příklady regulárních výrazů .
Tento dokument představuje přepis adres URL s pokyny k použití middlewaru pro přepis adres URL v aplikacích ASP.NET Core.
Přepsání adresy URL je úprava adres URL požadavků na základě jednoho nebo více předdefinovaných pravidel. Přepsání adresy URL vytvoří abstrakci mezi umístěními prostředků a jejich adresami, takže umístění a adresy nejsou úzce propojené. Přepsání adresy URL je cenné v několika scénářích pro:
- Přesuňte nebo nahraďte prostředky serveru dočasně nebo trvale a udržujte stabilní lokátory těchto prostředků.
- Rozdělte zpracování žádostí mezi různé aplikace nebo napříč oblastmi jedné aplikace.
- Odeberte, přidejte nebo reorganizujte segmenty adres URL u příchozích požadavků.
- Optimalizace veřejných adres URL pro optimalizaci vyhledávacích webů (SEO).
- Povolte použití přátelských veřejných adres URL, které návštěvníkům pomůžou předpovědět obsah vrácený žádostí o prostředek.
- Přesměrujte nezabezpečené požadavky na zabezpečené koncové body.
- Znemožnit propojení s hotlinkingem, kdy externí web používá hostovaný statický prostředek na jiném webu propojením prostředku s vlastním obsahem.
Poznámka:
Přepsání adresy URL může snížit výkon aplikace. Pokud je to možné, omezte počet a složitost pravidel.
Zobrazení nebo stažení ukázkového kódu (postup stažení)
Přesměrování adresy URL a přepsání adresy URL
Rozdíl ve formulaci přesměrování adresy URL a přepsání adresy URL je malý, ale má důležité důsledky pro poskytování prostředků klientům. ASP.NET middlewaru pro přepis adresy URL jádra je schopen splnit potřebu obojího.
Přesměrování adresy URL zahrnuje operaci na straně klienta, kde se klientovi dá pokyn, aby přistupoval k prostředku na jiné adrese než původně požadovaný klient. To vyžaduje odezvu na server. Adresa URL přesměrování vrácená klientovi se zobrazí v adresní řádku prohlížeče, když klient provede nový požadavek na prostředek.
Pokud /resource
je přesměrování na /different-resource
server, server odpoví, že klient by měl získat prostředek se /different-resource
stavovým kódem označujícím, že přesměrování je dočasné nebo trvalé.
Při přesměrování požadavků na jinou adresu URL určete, jestli je přesměrování trvalé nebo dočasné, zadáním stavového kódu s odpovědí:
301 - Moved Permanently
Stavový kód se používá, pokud má prostředek novou, trvalou adresu URL a chcete dát klientovi pokyn, aby všechny budoucí požadavky na prostředek měly používat novou adresu URL. Klient může ukládat odpověď do mezipaměti a opakovaně používat při přijetí stavového kódu 301.Stavový kód 302 – Nalezený se používá, pokud je přesměrování dočasné nebo obecně se může změnit. Stavový kód 302 označuje klientovi, aby neukládal adresu URL a v budoucnu ji používal.
Další informace o stavových kódech najdete v dokumentu RFC 9110: Definice stavových kódů.
Přepsání adresy URL je operace na straně serveru, která poskytuje prostředek z jiné adresy prostředku, než si klient vyžádal. Přepsání adresy URL nevyžaduje odezvu na server. Přepsaná adresa URL se klientovi nevrátí a nezobrazuje se v adresním řádku prohlížeče.
Pokud /resource
se přepíše , /different-resource
server interně načte a vrátí prostředek na adrese /different-resource
.
I když klient může být schopen načíst prostředek na přepsané adrese URL, klient není informován, že prostředek existuje na přepsané adrese URL, když odešle požadavek a obdrží odpověď.
Ukázková aplikace pro přepis adres URL
Pomocí ukázkové aplikace můžete prozkoumat funkce middlewaru pro přepis adres URL. Aplikace použije pravidla přesměrování a přepsání a zobrazí přesměrovanou nebo přepsanou adresu URL pro několik scénářů.
Kdy použít middleware pro přepis adres URL
Pokud nemůžete použít následující přístupy, použijte middleware pro přepis adres URL:
- Modul přepsání adresy URL službou IIS na Windows Serveru
- Modul Apache mod_rewrite na Apache Serveru
- Přepsání adresy URL ve službě Nginx
Při hostování aplikace na HTTP.sys serveru použijte middleware pro přepis adres URL.
Hlavními důvody použití technologií přepisování adres URL na serveru ve službě IIS, Apache a Nginx jsou:
Middleware nepodporuje úplné funkce těchto modulů.
Některé funkce modulů serveru nefungují s projekty ASP.NET Core, jako
IsFile
jsou například omezení modulu přepisování služby IIS aIsDirectory
omezení. V těchto scénářích místo toho použijte middleware.Výkon middlewaru pravděpodobně neodpovídá výkonu modulů.
Srovnávací testy jsou jediným způsobem, jak zjistit, který přístup snižuje výkon nejvíce nebo pokud je snížený výkon zanedbatelný.
Balíček
Middleware pro přepis adres URL poskytuje balíček Microsoft.AspNetCore.Rewrite , který je implicitně součástí aplikací ASP.NET Core.
Rozšíření a možnosti
Vytvořte pravidla přepsání adresy URL a přesměrování vytvořením instance třídy RewriteOptions s rozšiřujícími metodami pro každou pravidla přepsání. Zřetězte více pravidel v pořadí, v jakém je chcete zpracovat. Předávají RewriteOptions
se do middlewaru pro přepis adresy URL při přidání do kanálu požadavku:UseRewriter
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}"));
}
Přesměrovat jiné než www na www
Tři možnosti umožňují aplikaci přesměrovat požadavky,www
na www
které nejsou požadavky:
AddRedirectToWwwPermanent: Trvale přesměrujte požadavek na subdoménu
www
, pokud požadavek neníwww
. Přesměruje se stavovým kódem Status308PermanentRedirect .AddRedirectToWww: Přesměrujte požadavek na subdoménu
www
, pokud příchozí požadavek neníwww
. Přesměruje se stavovým kódem Status307TemporaryRedirect . Přetížení umožňuje zadat stavový kód odpovědi. Pro přiřazení stavového kódu použijte pole StatusCodes třídy.
Přesměrování adresy URL
Slouží AddRedirect k přesměrování požadavků. První parametr obsahuje regulární výraz pro párování na cestě příchozí adresy URL. Druhým parametrem je náhradní řetězec. Třetí parametr, pokud je k dispozici, určuje stavový kód. Pokud nezadáte stavový kód, výchozí stavový kód je 302 – Nalezeno, což znamená, že se prostředek dočasně přesune nebo nahradí.
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}"));
}
V prohlížeči s povolenými vývojářskými nástroji vytvořte požadavek na ukázkovou aplikaci s cestou /redirect-rule/1234/5678
. Regulární výraz odpovídá cestě požadavku na a redirect-rule/(.*)
cesta se nahradí znakem /redirected/1234/5678
. Adresa URL přesměrování se odešle zpět klientovi se stavovým kódem 302. Prohlížeč vytvoří nový požadavek na adresu URL přesměrování, která se zobrazí v adresní řádku prohlížeče. Vzhledem k tomu, že se žádná pravidla v ukázkové aplikaci neshoduje s adresou URL pro přesměrování:
- Druhý požadavek obdrží odpověď 200 – OK z aplikace.
- Text odpovědi zobrazuje adresu URL pro přesměrování.
Při přesměrování adresy URL se na server provede odezva.
Upozorňující
Při vytváření pravidel přesměrování buďte opatrní. Pravidla přesměrování se vyhodnocují při každém požadavku na aplikaci, včetně po přesměrování. Náhodné vytvoření smyčky nekonečných přesměrování je snadné.
Původní žádost: /redirect-rule/1234/5678
Část výrazu obsaženého v závorkách se nazývá skupina zachycení. Tečka (.
) výrazu odpovídá libovolnému znaku. Hvězdička (*
) označuje shodu s předchozím znakem nula nebo vícekrát. Proto jsou poslední dva segmenty cesty adresy URL zachyceny 1234/5678
skupinou (.*)
zachycení . Jakákoli hodnota, kterou zadáte v adrese URL požadavku, po redirect-rule/
zachycení touto jednou skupinou zachycení.
V náhradním řetězci se zachycené skupiny vloží do řetězce se znaménkem dolaru ($
) následovaným pořadovým číslem zachycení. První hodnota skupiny zachycení se získá s $1
hodnotou , druhou s $2
a budou pokračovat v sekvenci pro skupiny zachycení ve vašem regulárním výrazu. V ukázkové aplikaci existuje pouze jedna zachycená skupina pravidel přesměrování, takže v náhradním řetězci je pouze jedna vložená skupina, což je $1
. Při použití pravidla se adresa URL stane /redirected/1234/5678
.
Přesměrování adresy URL na zabezpečený koncový bod
Slouží AddRedirectToHttps k přesměrování požadavků HTTP na stejného hostitele a cestu pomocí protokolu HTTPS. Pokud stavový kód není zadaný, middleware se ve výchozím nastavení nastaví na hodnotu 302 – Nalezeno. Pokud port není zadaný:
- Ve výchozím nastavení se middleware nastaví na
null
. - Schéma se změní na
https
protokol HTTPS a klient přistupuje k prostředku na portu 443.
Následující příklad ukazuje, jak nastavit stavový kód na 301 - Moved Permanently
a změnit port na 5001.
public void Configure(IApplicationBuilder app)
{
var options = new RewriteOptions()
.AddRedirectToHttps(301, 5001);
app.UseRewriter(options);
}
Slouží AddRedirectToHttpsPermanent k přesměrování nezabezpečených požadavků na stejného hostitele a cestu se zabezpečeným protokolem HTTPS na portu 443. Middleware nastaví stavový kód na 301 - Moved Permanently
.
public void Configure(IApplicationBuilder app)
{
var options = new RewriteOptions()
.AddRedirectToHttpsPermanent();
app.UseRewriter(options);
}
Poznámka:
Při přesměrování na zabezpečený koncový bod bez požadavku na další pravidla přesměrování doporučujeme použít middleware přesměrování HTTPS. Další informace najdete v tématu Vynucení HTTPS .
Ukázková aplikace je schopná předvést, jak používat AddRedirectToHttps
nebo AddRedirectToHttpsPermanent
. Přidejte metodu rozšíření do souboru RewriteOptions
. Vytvořte pro aplikaci nezabezpečený požadavek na libovolnou adresu URL. Zavřete upozornění zabezpečení prohlížeče, že certifikát podepsaný svým držitelem je nedůvěryhodný, nebo vytvořte výjimku, která certifikátu důvěřuje.
Původní žádost pomocí AddRedirectToHttps(301, 5001)
: http://localhost:5000/secure
Původní žádost pomocí AddRedirectToHttpsPermanent
: http://localhost:5000/secure
Přepsání adresy URL
Slouží AddRewrite k vytvoření pravidla pro přepis adres URL. První parametr obsahuje regulární výraz pro porovnávání v cestě příchozí adresy URL. Druhým parametrem je náhradní řetězec. Třetí parametr , skipRemainingRules: {true|false}
označuje middleware zda přeskočit další přepis pravidla, pokud je aktuální pravidlo použito.
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}"));
}
Původní žádost: /rewrite-rule/1234/5678
Karat (^
) na začátku výrazu znamená, že porovnávání začíná na začátku cesty URL.
V předchozím příkladu s pravidlem redirect-rule/(.*)
přesměrování neexistuje na začátku regulárního výrazu žádný karat (^
). Proto všechny znaky mohou předcházet redirect-rule/
v cestě pro úspěšnou shodu.
Cesta | Párování |
---|---|
/redirect-rule/1234/5678 |
Ano |
/my-cool-redirect-rule/1234/5678 |
Ano |
/anotherredirect-rule/1234/5678 |
Yes |
Pravidlo přepsání odpovídá ^rewrite-rule/(\d+)/(\d+)
pouze cestám, pokud začínají rewrite-rule/
na . V následující tabulce si všimněte rozdílu ve shodě.
Cesta | Párování |
---|---|
/rewrite-rule/1234/5678 |
Yes |
/my-cool-rewrite-rule/1234/5678 |
No |
/anotherrewrite-rule/1234/5678 |
Ne |
^rewrite-rule/
Za částí výrazu jsou dvě skupiny zachycení , (\d+)/(\d+)
. Symboly \d
odpovídají číslici (číslo). Znaménko plus (+
) znamená shodu s jedním nebo více předchozím znakem. Proto musí adresa URL obsahovat číslo následované lomítkem následovaným jiným číslem. Tyto skupiny zachycení se vloží do přepsané adresy URL jako $1
a $2
. Řetězec nahrazení pravidla přepsáním umístí zachycené skupiny do řetězce dotazu. Požadovaná cesta /rewrite-rule/1234/5678
je přepsána pro získání prostředku na /rewritten?var1=1234&var2=5678
adrese . Pokud v původním požadavku existuje řetězec dotazu, zachová se při přepsání adresy URL.
Na server neexistuje žádná zpáteční cesta k získání prostředku. Pokud prostředek existuje, načte se a vrátí klientovi se stavovým kódem 200 – OK . Vzhledem k tomu, že klient není přesměrován, adresa URL v adresní řádku prohlížeče se nezmění. Klienti nemůžou zjistit, že na serveru došlo k operaci přepsání adresy URL.
Poznámka:
Kdykoli skipRemainingRules: true
je to možné, protože odpovídající pravidla jsou výpočetně náročná a zvyšují dobu odezvy aplikace. Nejrychlejší odezva aplikace:
- Pravidla přepisování objednávek z nejčastěji vyhovujícího pravidla na pravidlo, které odpovídá nejméně často.
- Přeskočte zpracování zbývajících pravidel, když dojde ke shodě, a nevyžaduje se žádné další zpracování pravidel.
Apache mod_rewrite
Použití pravidel Apache mod_rewrite s AddApacheModRewrite. Ujistěte se, že je soubor pravidel nasazený s aplikací. Další informace a příklady pravidel mod_rewrite najdete v tématu Apache mod_rewrite.
A StreamReader slouží ke čtení pravidel ze souboru pravidel ApacheModRewrite.txt :
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}"));
}
Ukázková aplikace přesměruje požadavky z /apache-mod-rules-redirect/(.\*)
./redirected?id=$1
Stavový kód odpovědi je 302 – Nalezeno.
# Rewrite path with additional sub directory
RewriteRule ^/apache-mod-rules-redirect/(.*) /redirected?id=$1 [L,R=302]
Původní žádost: /apache-mod-rules-redirect/1234
Middleware podporuje následující proměnné serveru Apache mod_rewrite:
- 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
Pravidla modulu přepsání adresy URL služby IIS
Chcete-li použít stejnou sadu pravidel, která se vztahuje na modul přepsání adresy URL služby IIS, použijte AddIISUrlRewrite. Ujistěte se, že je soubor pravidel nasazený s aplikací. Nesměrujte middleware tak, aby při spuštění ve službě Windows Server IIS používal soubor web.config aplikace. U služby IIS by tato pravidla měla být uložena mimo soubor web.config aplikace, aby nedocházelo ke konfliktům s modulem iis Rewrite. Další informace a příklady pravidel modulu přepsání adresy URL služby IIS naleznete v tématu Použití modulu přepsání adresy URL 2.0 a odkazy na konfiguraci modulu přepisu adresy URL.
A StreamReader slouží ke čtení pravidel ze IISUrlRewrite.xml
souboru pravidel:
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}"));
}
Ukázková aplikace přepisuje požadavky z /iis-rules-rewrite/(.*)
do /rewritten?id=$1
. Odpověď se odešle klientovi se stavovým kódem 200 – OK .
<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>
Původní žádost: /iis-rules-rewrite/1234
Pokud máte aktivní modul pro přepis služby IIS s nakonfigurovanými pravidly na úrovni serveru, která by ovlivnila vaši aplikaci nežádoucími způsoby, můžete pro aplikaci zakázat modul pro přepis služby IIS. Další informace naleznete v tématu Zakázání modulů služby IIS.
Nepodporované funkce
Middleware nepodporuje následující funkce modulu přepsání adresy URL služby IIS:
- Pravidla pro odchozí provoz
- Vlastní proměnné serveru
- Zástupné znaky
- LogRewrittenUrl
Podporované proměnné serveru
Middleware podporuje následující proměnné serveru modulu pro přepsání adresy URL služby IIS:
- 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
Poznámka:
Můžete také získat IFileProvider prostřednictvím PhysicalFileProvider. Tento přístup může poskytovat větší flexibilitu pro umístění souborů pravidel přepsání. Ujistěte se, že jsou soubory pravidel přepsání nasazené na server v zadané cestě.
PhysicalFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());
Pravidlo založené na metodách
Slouží Add k implementaci vlastní logiky pravidla v metodě. Add
RewriteContextzveřejňuje , který zpřístupňuje HttpContext pro použití ve vaší metodě. RewriteContext.Result určuje, jak se zpracovává další zpracování kanálu. Nastavte hodnotu na jedno z RuleResult polí popsaných v následující tabulce.
Přepsat výsledek kontextu | Akce |
---|---|
RuleResult.ContinueRules (výchozí) |
Pokračujte v používání pravidel. |
RuleResult.EndResponse |
Ukončete použití pravidel a odešlete odpověď. |
RuleResult.SkipRemainingRules |
Ukončete použití pravidel a odešlete kontext do dalšího middlewaru. |
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}"));
}
Ukázková aplikace ukazuje metodu, která přesměruje požadavky na cesty, které končí .xml
. Pokud je žádost podána /file.xml
, žádost se přesměruje na /xmlfiles/file.xml
. Stavový kód je nastaven na 301 - Moved Permanently
hodnotu . Když prohlížeč vytvoří nový požadavek na /xmlfiles/file.xml
, statický soubor Middleware obsluhuje soubor klientovi ze složky wwwroot/xmlfiles . Pro přesměrování explicitně nastavte stavový kód odpovědi. V opačném případě se vrátí stavový kód 200 – OK a v klientovi nedojde k přesměrování.
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;
}
}
Tento přístup může také přepsat požadavky. Ukázková aplikace ukazuje přepsání cesty pro jakýkoli požadavek na textový soubor, který bude sloužit file.txt textovému souboru ze složky wwwroot. Middleware statického souboru slouží k souboru na základě aktualizované cesty požadavku:
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";
}
}
Pravidlo založené na IRule
Používá Add se k použití logiky pravidla ve třídě, která implementuje IRule rozhraní. IRule
poskytuje větší flexibilitu při používání přístupu založeného na metodách. Třída implementace může obsahovat konstruktor, který umožňuje předat parametry pro metodu ApplyRule .
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}"));
}
Hodnoty parametrů v ukázkové aplikaci a extension
jsou newPath
kontrolovány tak, aby splňovaly několik podmínek. Musí extension
obsahovat hodnotu a hodnota musí být .png
, .jpg
nebo .gif. newPath
Pokud není platný, vyvolá se chybaArgumentException. Pokud je žádost podána image.png
, žádost se přesměruje na /png-images/image.png
. Pokud je žádost podána image.jpg
, žádost se přesměruje na /jpg-images/image.jpg
. Stavový kód je nastaven na hodnotu a context.Result
je nastaven na 301 - Moved Permanently
zastavení zpracování pravidel a odeslání odpovědi.
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;
}
}
}
Původní žádost: /image.png
Původní žádost: /image.jpg
Příklady regulárních výrazů
Goal | Řetězec regulárního výrazu a Příklad shody |
Náhradní řetězec &. Příklad výstupu |
---|---|---|
Přepsání cesty do řetězce dotazu | ^path/(.*)/(.*) /path/abc/123 |
path?var1=$1&var2=$2 /path?var1=abc&var2=123 |
Pruh koncové lomítko | (.*)/$ /path/ |
$1 /path |
Vynucení koncového lomítka | (.*[^/])$ /path |
$1/ /path/ |
Vyhněte se přepisování konkrétních požadavků | ^(.*)(?<!\.axd)$ nebo ^(?!.*\.axd$)(.*)$ Ano: /resource.htm Ne: /resource.axd |
rewritten/$1 /rewritten/resource.htm /resource.axd |
Změna uspořádání segmentů adres URL | path/(.*)/(.*)/(.*) path/1/2/3 |
path/$3/$2/$1 path/3/2/1 |
Nahrazení segmentu adresy URL | ^(.*)/segment2/(.*) /segment1/segment2/segment3 |
$1/replaced/$2 /segment1/replaced/segment3 |
Tento dokument představuje přepis adres URL s pokyny k použití middlewaru pro přepis adres URL v aplikacích ASP.NET Core.
Přepsání adresy URL je úprava adres URL požadavků na základě jednoho nebo více předdefinovaných pravidel. Přepsání adresy URL vytvoří abstrakci mezi umístěními prostředků a jejich adresami, takže umístění a adresy nejsou úzce propojené. Přepsání adresy URL je cenné v několika scénářích pro:
- Přesuňte nebo nahraďte prostředky serveru dočasně nebo trvale a udržujte stabilní lokátory těchto prostředků.
- Rozdělte zpracování žádostí mezi různé aplikace nebo napříč oblastmi jedné aplikace.
- Odeberte, přidejte nebo reorganizujte segmenty adres URL u příchozích požadavků.
- Optimalizace veřejných adres URL pro optimalizaci vyhledávacích webů (SEO).
- Povolte použití přátelských veřejných adres URL, které návštěvníkům pomůžou předpovědět obsah vrácený žádostí o prostředek.
- Přesměrujte nezabezpečené požadavky na zabezpečené koncové body.
- Znemožnit propojení s hotlinkingem, kdy externí web používá hostovaný statický prostředek na jiném webu propojením prostředku s vlastním obsahem.
Poznámka:
Přepsání adresy URL může snížit výkon aplikace. Pokud je to možné, omezte počet a složitost pravidel.
Zobrazení nebo stažení ukázkového kódu (postup stažení)
Přesměrování adresy URL a přepsání adresy URL
Rozdíl ve formulaci přesměrování adresy URL a přepsání adresy URL je malý, ale má důležité důsledky pro poskytování prostředků klientům. ASP.NET middlewaru pro přepis adresy URL jádra je schopen splnit potřebu obojího.
Přesměrování adresy URL zahrnuje operaci na straně klienta, kde se klientovi dá pokyn, aby přistupoval k prostředku na jiné adrese než původně požadovaný klient. To vyžaduje odezvu na server. Adresa URL přesměrování vrácená klientovi se zobrazí v adresní řádku prohlížeče, když klient provede nový požadavek na prostředek.
Pokud /resource
je přesměrování na /different-resource
server, server odpoví, že klient by měl získat prostředek se /different-resource
stavovým kódem označujícím, že přesměrování je dočasné nebo trvalé.
Při přesměrování požadavků na jinou adresu URL určete, jestli je přesměrování trvalé nebo dočasné, zadáním stavového kódu s odpovědí:
301 - Moved Permanently
Stavový kód se používá, pokud má prostředek novou, trvalou adresu URL a chcete dát klientovi pokyn, aby všechny budoucí požadavky na prostředek měly používat novou adresu URL. Klient může ukládat odpověď do mezipaměti a opakovaně používat při přijetí stavového kódu 301.Stavový kód 302 – Nalezený se používá, pokud je přesměrování dočasné nebo obecně se může změnit. Stavový kód 302 označuje klientovi, aby neukládal adresu URL a v budoucnu ji používal.
Další informace o stavových kódech najdete v dokumentu RFC 9110: Definice stavových kódů.
Přepsání adresy URL je operace na straně serveru, která poskytuje prostředek z jiné adresy prostředku, než si klient vyžádal. Přepsání adresy URL nevyžaduje odezvu na server. Přepsaná adresa URL se klientovi nevrátí a nezobrazuje se v adresním řádku prohlížeče.
Pokud /resource
se přepíše , /different-resource
server interně načte a vrátí prostředek na adrese /different-resource
.
I když klient může být schopen načíst prostředek na přepsané adrese URL, klient není informován, že prostředek existuje na přepsané adrese URL, když odešle požadavek a obdrží odpověď.
Ukázková aplikace pro přepis adres URL
Pomocí ukázkové aplikace můžete prozkoumat funkce middlewaru pro přepis adres URL. Aplikace použije pravidla přesměrování a přepsání a zobrazí přesměrovanou nebo přepsanou adresu URL pro několik scénářů.
Kdy použít middleware pro přepsání adresy URL
Pokud nemůžete použít následující přístupy, použijte middleware pro přepis adres URL:
- Modul přepsání adresy URL službou IIS na Windows Serveru
- Modul Apache mod_rewrite na Apache Serveru
- Přepsání adresy URL ve službě Nginx
Také použijte middleware, když je aplikace hostovaná na HTTP.sys serveru (dříve označované jako WebListener).
Hlavními důvody použití technologií přepisování adres URL na serveru ve službě IIS, Apache a Nginx jsou:
Middleware nepodporuje úplné funkce těchto modulů.
Některé funkce modulů serveru nefungují s projekty ASP.NET Core, jako
IsFile
jsou například omezení modulu přepisování služby IIS aIsDirectory
omezení. V těchto scénářích místo toho použijte middleware.Výkon middlewaru pravděpodobně neodpovídá výkonu modulů.
Srovnávací testy jsou jediným způsobem, jak zjistit, který přístup snižuje výkon nejvíce nebo pokud je snížený výkon zanedbatelný.
Balíček
Pokud chcete do projektu zahrnout middleware, přidejte do souboru projektu odkaz na balíček Microsoft.AspNetCore.App metabalíku , který obsahuje balíček Microsoft.AspNetCore.Rewrite .
Pokud metabalíč nepoužíváte Microsoft.AspNetCore.App
, přidejte do balíčku odkaz na Microsoft.AspNetCore.Rewrite
projekt.
Rozšíření a možnosti
Vytvořte pravidla přepsání adresy URL a přesměrování vytvořením instance třídy RewriteOptions s rozšiřujícími metodami pro každou pravidla přepsání. Zřetězte více pravidel v pořadí, v jakém je chcete zpracovat. Předávají RewriteOptions
se do middlewaru pro přepis adresy URL při přidání do kanálu požadavku:UseRewriter
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}"));
}
Přesměrovat jiné než www na www
Tři možnosti umožňují aplikaci přesměrovat požadavky,www
na www
které nejsou požadavky:
AddRedirectToWwwPermanent: Trvale přesměrujte požadavek na subdoménu
www
, pokud požadavek neníwww
. Přesměruje se stavovým kódem Status308PermanentRedirect .AddRedirectToWww: Přesměrujte požadavek na subdoménu
www
, pokud příchozí požadavek neníwww
. Přesměruje se stavovým kódem Status307TemporaryRedirect . Přetížení umožňuje zadat stavový kód odpovědi. Pro přiřazení stavového kódu použijte pole StatusCodes třídy.
Přesměrování adresy URL
Slouží AddRedirect k přesměrování požadavků. První parametr obsahuje regulární výraz pro párování na cestě příchozí adresy URL. Druhým parametrem je náhradní řetězec. Třetí parametr, pokud je k dispozici, určuje stavový kód. Pokud nezadáte stavový kód, výchozí stavový kód je 302 – Nalezeno, což znamená, že se prostředek dočasně přesune nebo nahradí.
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}"));
}
V prohlížeči s povolenými vývojářskými nástroji vytvořte požadavek na ukázkovou aplikaci s cestou /redirect-rule/1234/5678
. Regulární výraz odpovídá cestě požadavku na a redirect-rule/(.*)
cesta se nahradí znakem /redirected/1234/5678
. Adresa URL přesměrování se odešle zpět klientovi se stavovým kódem 302. Prohlížeč vytvoří nový požadavek na adresu URL přesměrování, která se zobrazí v adresní řádku prohlížeče. Vzhledem k tomu, že se žádná pravidla v ukázkové aplikaci neshoduje s adresou URL pro přesměrování:
- Druhý požadavek obdrží odpověď 200 – OK z aplikace.
- Text odpovědi zobrazuje adresu URL pro přesměrování.
Při přesměrování adresy URL se na server provede odezva.
Upozorňující
Při vytváření pravidel přesměrování buďte opatrní. Pravidla přesměrování se vyhodnocují při každém požadavku na aplikaci, včetně po přesměrování. Náhodné vytvoření smyčky nekonečných přesměrování je snadné.
Původní žádost: /redirect-rule/1234/5678
Část výrazu obsaženého v závorkách se nazývá skupina zachycení. Tečka (.
) výrazu odpovídá libovolnému znaku. Hvězdička (*
) označuje shodu s předchozím znakem nula nebo vícekrát. Proto jsou poslední dva segmenty cesty adresy URL zachyceny 1234/5678
skupinou (.*)
zachycení . Jakákoli hodnota, kterou zadáte v adrese URL požadavku, po redirect-rule/
zachycení touto jednou skupinou zachycení.
V náhradním řetězci se zachycené skupiny vloží do řetězce se znaménkem dolaru ($
) následovaným pořadovým číslem zachycení. První hodnota skupiny zachycení se získá s $1
hodnotou , druhou s $2
a budou pokračovat v sekvenci pro skupiny zachycení ve vašem regulárním výrazu. V ukázkové aplikaci existuje pouze jedna zachycená skupina pravidel přesměrování, takže v náhradním řetězci je pouze jedna vložená skupina, což je $1
. Při použití pravidla se adresa URL stane /redirected/1234/5678
.
Přesměrování adresy URL na zabezpečený koncový bod
Slouží AddRedirectToHttps k přesměrování požadavků HTTP na stejného hostitele a cestu pomocí protokolu HTTPS. Pokud stavový kód není zadaný, middleware se ve výchozím nastavení nastaví na hodnotu 302 – Nalezeno. Pokud port není zadaný:
- Ve výchozím nastavení se middleware nastaví na
null
. - Schéma se změní na
https
protokol HTTPS a klient přistupuje k prostředku na portu 443.
Následující příklad ukazuje, jak nastavit stavový kód na 301 - Moved Permanently
a změnit port na 5001.
public void Configure(IApplicationBuilder app)
{
var options = new RewriteOptions()
.AddRedirectToHttps(301, 5001);
app.UseRewriter(options);
}
Slouží AddRedirectToHttpsPermanent k přesměrování nezabezpečených požadavků na stejného hostitele a cestu se zabezpečeným protokolem HTTPS na portu 443. Middleware nastaví stavový kód na 301 - Moved Permanently
.
public void Configure(IApplicationBuilder app)
{
var options = new RewriteOptions()
.AddRedirectToHttpsPermanent();
app.UseRewriter(options);
}
Poznámka:
Při přesměrování na zabezpečený koncový bod bez požadavku na další pravidla přesměrování doporučujeme použít middleware přesměrování HTTPS. Další informace najdete v tématu Vynucení HTTPS .
Ukázková aplikace je schopná předvést, jak používat AddRedirectToHttps
nebo AddRedirectToHttpsPermanent
. Přidejte metodu rozšíření do souboru RewriteOptions
. Vytvořte pro aplikaci nezabezpečený požadavek na libovolnou adresu URL. Zavřete upozornění zabezpečení prohlížeče, že certifikát podepsaný svým držitelem je nedůvěryhodný, nebo vytvořte výjimku, která certifikátu důvěřuje.
Původní žádost pomocí AddRedirectToHttps(301, 5001)
: http://localhost:5000/secure
Původní žádost pomocí AddRedirectToHttpsPermanent
: http://localhost:5000/secure
Přepsání adresy URL
Slouží AddRewrite k vytvoření pravidla pro přepis adres URL. První parametr obsahuje regulární výraz pro porovnávání v cestě příchozí adresy URL. Druhým parametrem je náhradní řetězec. Třetí parametr , skipRemainingRules: {true|false}
označuje middleware zda přeskočit další přepis pravidla, pokud je aktuální pravidlo použito.
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}"));
}
Původní žádost: /rewrite-rule/1234/5678
Karat (^
) na začátku výrazu znamená, že porovnávání začíná na začátku cesty URL.
V předchozím příkladu s pravidlem redirect-rule/(.*)
přesměrování neexistuje na začátku regulárního výrazu žádný karat (^
). Proto všechny znaky mohou předcházet redirect-rule/
v cestě pro úspěšnou shodu.
Cesta | Párování |
---|---|
/redirect-rule/1234/5678 |
Ano |
/my-cool-redirect-rule/1234/5678 |
Ano |
/anotherredirect-rule/1234/5678 |
Yes |
Pravidlo přepsání odpovídá ^rewrite-rule/(\d+)/(\d+)
pouze cestám, pokud začínají rewrite-rule/
na . V následující tabulce si všimněte rozdílu ve shodě.
Cesta | Párování |
---|---|
/rewrite-rule/1234/5678 |
Yes |
/my-cool-rewrite-rule/1234/5678 |
No |
/anotherrewrite-rule/1234/5678 |
Ne |
^rewrite-rule/
Za částí výrazu jsou dvě skupiny zachycení , (\d+)/(\d+)
. Symboly \d
odpovídají číslici (číslo). Znaménko plus (+
) znamená shodu s jedním nebo více předchozím znakem. Proto musí adresa URL obsahovat číslo následované lomítkem následovaným jiným číslem. Tyto skupiny zachycení se vloží do přepsané adresy URL jako $1
a $2
. Řetězec nahrazení pravidla přepsáním umístí zachycené skupiny do řetězce dotazu. Požadovaná cesta /rewrite-rule/1234/5678
je přepsána pro získání prostředku na /rewritten?var1=1234&var2=5678
adrese . Pokud v původním požadavku existuje řetězec dotazu, zachová se při přepsání adresy URL.
Na server neexistuje žádná zpáteční cesta k získání prostředku. Pokud prostředek existuje, načte se a vrátí klientovi se stavovým kódem 200 – OK . Vzhledem k tomu, že klient není přesměrován, adresa URL v adresní řádku prohlížeče se nezmění. Klienti nemůžou zjistit, že na serveru došlo k operaci přepsání adresy URL.
Poznámka:
Kdykoli skipRemainingRules: true
je to možné, protože odpovídající pravidla jsou výpočetně náročná a zvyšují dobu odezvy aplikace. Nejrychlejší odezva aplikace:
- Pravidla přepisování objednávek z nejčastěji vyhovujícího pravidla na pravidlo, které odpovídá nejméně často.
- Přeskočte zpracování zbývajících pravidel, když dojde ke shodě, a nevyžaduje se žádné další zpracování pravidel.
Apache mod_rewrite
Použití pravidel Apache mod_rewrite s AddApacheModRewrite. Ujistěte se, že je soubor pravidel nasazený s aplikací. Další informace a příklady pravidel mod_rewrite najdete v tématu Apache mod_rewrite.
A StreamReader slouží ke čtení pravidel ze souboru pravidel ApacheModRewrite.txt :
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}"));
}
Ukázková aplikace přesměruje požadavky z /apache-mod-rules-redirect/(.\*)
./redirected?id=$1
Stavový kód odpovědi je 302 – Nalezeno.
# Rewrite path with additional sub directory
RewriteRule ^/apache-mod-rules-redirect/(.*) /redirected?id=$1 [L,R=302]
Původní žádost: /apache-mod-rules-redirect/1234
Middleware podporuje následující proměnné serveru Apache mod_rewrite:
- 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
Pravidla modulu přepsání adresy URL služby IIS
Chcete-li použít stejnou sadu pravidel, která se vztahuje na modul přepsání adresy URL služby IIS, použijte AddIISUrlRewrite. Ujistěte se, že je soubor pravidel nasazený s aplikací. Nesměrujte middleware tak, aby při spuštění ve službě Windows Server IIS používal soubor web.config aplikace. U služby IIS by tato pravidla měla být uložena mimo soubor web.config aplikace, aby nedocházelo ke konfliktům s modulem iis Rewrite. Další informace a příklady pravidel modulu přepsání adresy URL služby IIS naleznete v tématu Použití modulu přepsání adresy URL 2.0 a odkazy na konfiguraci modulu přepisu adresy URL.
A StreamReader slouží ke čtení pravidel ze IISUrlRewrite.xml
souboru pravidel:
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}"));
}
Ukázková aplikace přepisuje požadavky z /iis-rules-rewrite/(.*)
do /rewritten?id=$1
. Odpověď se odešle klientovi se stavovým kódem 200 – OK .
<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>
Původní žádost: /iis-rules-rewrite/1234
Pokud máte aktivní modul pro přepis služby IIS s nakonfigurovanými pravidly na úrovni serveru, která by ovlivnila vaši aplikaci nežádoucími způsoby, můžete pro aplikaci zakázat modul pro přepis služby IIS. Další informace naleznete v tématu Zakázání modulů služby IIS.
Nepodporované funkce
Middleware vydaný s ASP.NET Core 2.x nepodporuje následující funkce modulu přepsání adresy URL služby IIS:
- Pravidla pro odchozí provoz
- Vlastní proměnné serveru
- Zástupné znaky
- LogRewrittenUrl
Podporované proměnné serveru
Middleware podporuje následující proměnné serveru modulu pro přepsání adresy URL služby IIS:
- 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
Poznámka:
Můžete také získat IFileProvider prostřednictvím PhysicalFileProvider. Tento přístup může poskytovat větší flexibilitu pro umístění souborů pravidel přepsání. Ujistěte se, že jsou soubory pravidel přepsání nasazené na server v zadané cestě.
PhysicalFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());
Pravidlo založené na metodách
Slouží Add k implementaci vlastní logiky pravidla v metodě. Add
RewriteContextzveřejňuje , který zpřístupňuje HttpContext pro použití ve vaší metodě. RewriteContext.Result určuje, jak se zpracovává další zpracování kanálu. Nastavte hodnotu na jedno z RuleResult polí popsaných v následující tabulce.
Přepsat výsledek kontextu | Akce |
---|---|
RuleResult.ContinueRules (výchozí) |
Pokračujte v používání pravidel. |
RuleResult.EndResponse |
Ukončete použití pravidel a odešlete odpověď. |
RuleResult.SkipRemainingRules |
Ukončete použití pravidel a odešlete kontext do dalšího middlewaru. |
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}"));
}
Ukázková aplikace ukazuje metodu, která přesměruje požadavky na cesty, které končí .xml
. Pokud je žádost podána /file.xml
, žádost se přesměruje na /xmlfiles/file.xml
. Stavový kód je nastaven na 301 - Moved Permanently
hodnotu . Když prohlížeč vytvoří nový požadavek na /xmlfiles/file.xml
, statický soubor Middleware obsluhuje soubor klientovi ze složky wwwroot/xmlfiles . Pro přesměrování explicitně nastavte stavový kód odpovědi. V opačném případě se vrátí stavový kód 200 – OK a v klientovi nedojde k přesměrování.
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;
}
}
Tento přístup může také přepsat požadavky. Ukázková aplikace ukazuje přepsání cesty pro jakýkoli požadavek na textový soubor, který bude sloužit file.txt textovému souboru ze složky wwwroot. Middleware statického souboru slouží k souboru na základě aktualizované cesty požadavku:
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";
}
}
Pravidlo založené na IRule
Používá Add se k použití logiky pravidla ve třídě, která implementuje IRule rozhraní. IRule
poskytuje větší flexibilitu při používání přístupu založeného na metodách. Třída implementace může obsahovat konstruktor, který umožňuje předat parametry pro metodu ApplyRule .
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}"));
}
Hodnoty parametrů v ukázkové aplikaci a extension
jsou newPath
kontrolovány tak, aby splňovaly několik podmínek. Musí extension
obsahovat hodnotu a hodnota musí být .png
, .jpg
nebo .gif. newPath
Pokud není platný, vyvolá se chybaArgumentException. Pokud je žádost podána image.png
, žádost se přesměruje na /png-images/image.png
. Pokud je žádost podána image.jpg
, žádost se přesměruje na /jpg-images/image.jpg
. Stavový kód je nastaven na hodnotu a context.Result
je nastaven na 301 - Moved Permanently
zastavení zpracování pravidel a odeslání odpovědi.
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;
}
}
}
Původní žádost: /image.png
Původní žádost: /image.jpg
Příklady regulárních výrazů
Goal | Řetězec regulárního výrazu a Příklad shody |
Náhradní řetězec &. Příklad výstupu |
---|---|---|
Přepsání cesty do řetězce dotazu | ^path/(.*)/(.*) /path/abc/123 |
path?var1=$1&var2=$2 /path?var1=abc&var2=123 |
Pruh koncové lomítko | (.*)/$ /path/ |
$1 /path |
Vynucení koncového lomítka | (.*[^/])$ /path |
$1/ /path/ |
Vyhněte se přepisování konkrétních požadavků | ^(.*)(?<!\.axd)$ nebo ^(?!.*\.axd$)(.*)$ Ano: /resource.htm Ne: /resource.axd |
rewritten/$1 /rewritten/resource.htm /resource.axd |
Změna uspořádání segmentů adres URL | path/(.*)/(.*)/(.*) path/1/2/3 |
path/$3/$2/$1 path/3/2/1 |
Nahrazení segmentu adresy URL | ^(.*)/segment2/(.*) /segment1/segment2/segment3 |
$1/replaced/$2 /segment1/replaced/segment3 |
Další materiály
- Zobrazení nebo stažení ukázkového kódu (postup stažení)
- Přepsání zdrojeMiddleware na GitHubu
- Spuštění aplikace v ASP.NET Core
- ASP.NET Core Middleware
- Regulární výrazy v .NET
- Jazyk regulárních výrazů – stručná referenční dokumentace
- Apache mod_rewrite
- Použití modulu pro přepsání adresy URL 2.0 (pro iis)
- Referenční informace o konfiguraci modulu přepsání adresy URL
- Zachování jednoduché struktury adres URL
- 10 tipů a triků pro přepis adres URL
- Lomítko nebo ne lomítko