Penulisan Ulang URL Middleware di ASP.NET Core
Catatan
Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Peringatan
Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Penting
Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Oleh Kirk Larkin dan Rick Anderson
Artikel ini memperkenalkan penulisan ulang URL dengan instruksi tentang cara menggunakan URL Menulis Ulang Middleware di aplikasi ASP.NET Core.
Penulisan ulang URL adalah tindakan memodifikasi URL permintaan berdasarkan satu atau beberapa aturan yang telah ditentukan sebelumnya. Penulisan ulang URL membuat abstraksi antara lokasi sumber daya dan alamatnya sehingga lokasi dan alamat tidak ditautkan dengan erat. Penulisan ulang URL sangat berharga dalam beberapa skenario untuk:
- Pindahkan atau ganti sumber daya server untuk sementara atau permanen dan pertahankan pencari lokasi yang stabil untuk sumber daya tersebut.
- Memisahkan pemrosesan permintaan di berbagai aplikasi atau di seluruh area satu aplikasi.
- Menghapus, menambahkan, atau mengatur ulang segmen URL pada permintaan masuk.
- Optimalkan URL publik untuk Pengoptimalan Mesin Pencari (SEO).
- Izinkan penggunaan URL publik yang ramah untuk membantu pengunjung memprediksi konten yang dikembalikan dengan meminta sumber daya.
- Alihkan permintaan yang tidak aman ke titik akhir yang aman.
- Cegah hotlinking, di mana situs eksternal menggunakan aset statis yang dihosting di situs lain dengan menautkan aset ke kontennya sendiri.
Penulisan ulang URL dapat mengurangi performa aplikasi. Batasi jumlah dan kompleksitas aturan.
Pengalihan URL dan regenerasi URL
Perbedaan kata antara pengalihan URL dan penulisan ulang URL halus tetapi memiliki implikasi penting untuk menyediakan sumber daya kepada klien. ASP.NET Penulisan Ulang URL Core Middleware mampu memenuhi kebutuhan keduanya.
Pengalihan URL melibatkan operasi sisi klien, di mana klien diinstruksikan untuk mengakses sumber daya di alamat yang berbeda dari klien yang awalnya diminta. Ini memerlukan perjalanan pulang pergi ke server. URL pengalihan yang dikembalikan ke klien muncul di bilah alamat browser saat klien membuat permintaan baru untuk sumber daya.
Jika /resource
dialihkan ke /different-resource
, server merespons bahwa klien harus mendapatkan sumber daya di /different-resource
dengan kode status yang menunjukkan bahwa pengalihan bersifat sementara atau permanen.
Saat mengalihkan permintaan ke URL yang berbeda, tunjukkan apakah pengalihan bersifat permanen atau sementara dengan menentukan kode status dengan respons:
Kode
301 - Moved Permanently
status digunakan di mana sumber daya memiliki URL permanen baru dan bahwa semua permintaan di masa mendatang untuk sumber daya harus menggunakan URL baru. Klien dapat menyimpan dan menggunakan kembali respons saat kode status 301 diterima.Kode
302 - Found
status digunakan di mana pengalihan bersifat sementara atau umumnya dapat berubah. Kode status 302 menunjukkan kepada klien untuk tidak menyimpan URL dan menggunakannya di masa mendatang.
Untuk informasi selengkapnya tentang kode status, lihat RFC 9110: Definisi Kode Status.
Penulisan ulang URL adalah operasi sisi server yang menyediakan sumber daya dari alamat sumber daya yang berbeda dari yang diminta klien. Menulis ulang URL tidak memerlukan perjalanan pulang pergi ke server. URL yang ditulis ulang tidak dikembalikan ke klien dan tidak muncul di bilah alamat browser.
Jika /resource
ditulis ulang ke /different-resource
, server secara internal mengambil dan mengembalikan sumber daya di /different-resource
.
Meskipun klien mungkin dapat mengambil sumber daya di URL yang ditulis ulang, klien tidak diberi tahu bahwa sumber daya ada di URL yang ditulis ulang saat membuat permintaannya dan menerima respons.
Aplikasi sampel penulisan ulang URL
Jelajahi fitur URL Menulis Ulang Middleware dengan aplikasi sampel. Aplikasi ini menerapkan aturan pengalihan dan penulisan ulang dan menunjukkan URL yang dialihkan atau ditulis ulang untuk beberapa skenario.
Kapan menggunakan middleware penulisan ulang URL
Gunakan MIDDLEware Penulisan Ulang URL saat pendekatan berikut tidak memuaskan:
- Modul Penulisan Ulang URL dengan IIS di Windows Server
- Modul Apache mod_rewrite di Apache Server
- Penulisan ulang URL pada Nginx
Gunakan middleware penulisan ulang URL saat aplikasi dihosting di server HTTP.sys.
Alasan utama untuk menggunakan teknologi penulisan ulang URL berbasis server di IIS, Apache, dan Nginx adalah:
Middleware tidak mendukung fitur lengkap modul ini.
Beberapa fitur modul server tidak berfungsi dengan proyek ASP.NET Core, seperti
IsFile
batasan danIsDirectory
modul Penulisan Ulang IIS. Dalam skenario ini, gunakan middleware sebagai gantinya.Performa middleware mungkin tidak cocok dengan modul.
Tolok ukur adalah satu-satunya cara untuk mengetahui dengan kepastian pendekatan mana yang paling banyak menurunkan performa atau jika performa yang terdegradasi dapat diabaikan.
Ekstensi dan opsi
Buat aturan penulisan ulang dan pengalihan URL dengan membuat instans kelas RewriteOptions dengan metode ekstensi untuk setiap aturan penulisan ulang. Rantai beberapa aturan dalam urutan yang harus diproses. RewriteOptions
diteruskan ke URL Menulis Ulang Middleware saat ditambahkan ke alur permintaan dengan 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();
Dalam kode sebelumnya, MethodRules
adalah kelas yang ditentukan pengguna. Lihat RewriteRules.cs
di artikel ini untuk informasi selengkapnya.
Mengalihkan non-www ke www
Tiga opsi mengizinkan aplikasi untuk mengalihkan permintaan non-kewww
www
:
AddRedirectToWwwPermanent: Alihkan permintaan secara permanen ke
www
subdomain jika permintaan non-www
. Pengalihan dengan kode status Status308PermanentRedirect .AddRedirectToWww: Alihkan permintaan ke
www
subdomain jika permintaan masuk non-www
. Pengalihan dengan kode status Status307TemporaryRedirect . Kelebihan beban memungkinkan penyediaan kode status untuk respons. Gunakan bidang StatusCodes kelas untuk penetapan kode status.
Pengalihan URL
Gunakan AddRedirect untuk mengalihkan permintaan. Parameter pertama berisi ekspresi reguler .NET (Regex) untuk pencocokan pada jalur URL masuk. Parameter kedua adalah string pengganti. Parameter ketiga, jika ada, menentukan kode status. Jika kode status tidak ditentukan, kode status default ke 302 - Ditemukan, yang menunjukkan bahwa sumber daya untuk sementara dipindahkan atau diganti.
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();
Di browser dengan alat pengembang diaktifkan, buat permintaan ke aplikasi sampel dengan jalur /redirect-rule/1234/5678
. Ekspresi reguler cocok dengan jalur permintaan pada redirect-rule/(.*)
, dan jalur diganti dengan /redirected/1234/5678
. URL pengalihan dikirim kembali ke klien dengan kode status 302 - Ditemukan . Browser membuat permintaan baru di URL pengalihan, yang muncul di bilah alamat browser. Karena tidak ada aturan dalam aplikasi sampel yang cocok pada URL pengalihan:
- Permintaan kedua menerima respons 200 - OK dari aplikasi.
- Isi respons menunjukkan URL pengalihan.
Perjalanan pulang pergi dilakukan ke server saat URL dialihkan.
Peringatan
Berhati-hatilah saat membuat aturan pengalihan. Aturan pengalihan dievaluasi pada setiap permintaan ke aplikasi, termasuk setelah pengalihan. Sangat mudah untuk secara tidak sengaja membuat perulangan pengalihan tak terbatas .
Bagian dari ekspresi yang terkandung dalam tanda kurung disebut grup pengambilan. Titik (.
) ekspresi berarti cocok dengan karakter apa pun. Tanda bintang (*
) menunjukkan kecocokan nol karakter sebelumnya atau lebih kali. Oleh karena itu, dua segmen jalur terakhir URL, 1234/5678
, ditangkap oleh grup (.*)
pengambilan . Nilai apa pun yang disediakan dalam URL permintaan setelah redirect-rule/
diambil oleh grup penangkapan tunggal ini.
Dalam string pengganti, grup yang diambil disuntikkan ke dalam string dengan tanda dolar ($
) diikuti dengan nomor urut pengambilan. Nilai grup pengambilan pertama diperoleh dengan $1
, yang kedua dengan $2
, dan mereka melanjutkan secara berurutan untuk grup pengambilan dalam ekspresi reguler. Hanya ada satu grup yang diambil dalam regex aturan pengalihan di redirect-rule/(.*)
, sehingga hanya ada satu grup yang disuntikkan dalam string pengganti, yaitu $1
. Saat aturan diterapkan, URL menjadi /redirected/1234/5678
.
Coba /redirect-rule/1234/5678
dengan alat browser pada tab jaringan.
Pengalihan URL ke titik akhir yang aman
Gunakan AddRedirectToHttps untuk mengalihkan permintaan HTTP ke host dan jalur yang sama menggunakan protokol HTTPS. Jika kode status tidak disediakan, middleware default ke 302 - Ditemukan. Jika port tidak disediakan:
- Middleware default ke
null
. - Skema berubah menjadi
https
(protokol HTTPS), dan klien mengakses sumber daya pada port 443.
Contoh berikut menunjukkan cara mengatur kode status ke 301 - Moved Permanently
dan mengubah port ke port HTTPS yang digunakan oleh Kestrel pada localhost. Dalam produksi, port HTTPS diatur ke 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();
Gunakan AddRedirectToHttpsPermanent untuk mengalihkan permintaan yang tidak aman ke host dan jalur yang sama dengan protokol HTTPS aman pada port 443. Middleware mengatur kode status ke 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();
Catatan
Saat mengalihkan ke titik akhir yang aman tanpa persyaratan untuk aturan pengalihan tambahan, sebaiknya gunakan Middleware Pengalihan HTTPS. Untuk informasi selengkapnya, lihat Memberlakukan HTTPS.
Aplikasi sampel menunjukkan cara menggunakan AddRedirectToHttps
atau AddRedirectToHttpsPermanent
. Buat permintaan HTTP yang tidak aman ke aplikasi di http://redirect6.azurewebsites.net/iis-rules-rewrite/xyz
. Saat menguji pengalihan HTTP ke HTTPS dengan localhost:
- Gunakan URL HTTP, yang memiliki port yang berbeda dari URL HTTPS. URL HTTP ada dalam
Properties/launchSettings.json
file. - Menghapus
s
darihttps://localhost/{port}
gagal karena localhost tidak merespons pada HTTP ke port HTTPS.
Gambar berikut menunjukkan gambar alat browser F12 dari permintaan untuk http://redirect6.azurewebsites.net/iis-rules-rewrite/xyz
menggunakan kode sebelumnya:
Penulisan ulang URL
Gunakan AddRewrite untuk membuat aturan untuk menulis ulang URL. Parameter pertama berisi ekspresi reguler untuk pencocokan pada jalur URL masuk. Parameter kedua adalah string pengganti. Parameter ketiga, skipRemainingRules: {true|false}
, menunjukkan kepada middleware apakah akan melewati aturan penulisan ulang tambahan atau tidak jika aturan saat ini diterapkan.
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();
Coba permintaan ke https://redirect6.azurewebsites.net/rewrite-rule/1234/5678
Tanda sisipan (^
) di awal ekspresi berarti bahwa pencocokan dimulai di awal jalur URL.
Dalam contoh sebelumnya dengan aturan pengalihan, redirect-rule/(.*)
, tidak ada tanda sisipan (^
) di awal ekspresi reguler. Oleh karena itu, setiap karakter dapat mendahului redirect-rule/
di jalur untuk kecocokan yang berhasil.
Jalur | Cocokkan |
---|---|
/redirect-rule/1234/5678 |
Ya |
/my-cool-redirect-rule/1234/5678 |
Ya |
/anotherredirect-rule/1234/5678 |
Ya |
Aturan penulisan ulang, ^rewrite-rule/(\d+)/(\d+)
, hanya cocok dengan jalur jika dimulai dengan rewrite-rule/
. Dalam tabel berikut, perhatikan perbedaan dalam pencocokan.
Jalur | Cocokkan |
---|---|
/rewrite-rule/1234/5678 |
Ya |
/my-cool-rewrite-rule/1234/5678 |
No |
/anotherrewrite-rule/1234/5678 |
Tidak |
^rewrite-rule/
Setelah bagian ekspresi, ada dua grup pengambilan, (\d+)/(\d+)
. Menandakan \d
cocok dengan digit (angka). Tanda plus (+
) berarti cocok dengan satu atau beberapa karakter sebelumnya. Oleh karena itu, URL harus berisi angka yang diikuti dengan garis miring diikuti dengan angka lain. Grup penangkapan ini disuntikkan ke DALAM URL yang ditulis ulang sebagai $1
dan $2
. String penggantian aturan penulisan ulang menempatkan grup yang diambil ke dalam string kueri. Jalur /rewrite-rule/1234/5678
yang diminta ditulis ulang untuk mengembalikan sumber daya di /rewritten?var1=1234&var2=5678
. Jika string kueri ada pada permintaan asli, string tersebut dipertahankan saat URL ditulis ulang.
Tidak ada perjalanan pulang pergi ke server untuk mengembalikan sumber daya. Jika sumber daya ada, sumber daya diambil dan dikembalikan ke klien dengan kode status 200 - OK . Karena klien tidak dialihkan, URL di bilah alamat browser tidak berubah. Klien tidak dapat mendeteksi bahwa operasi penulisan ulang URL terjadi di server.
Tips performa untuk penulisan ulang dan pengalihan URL
Untuk respons tercepat:
- Aturan penulisan ulang pesanan dari aturan yang paling sering cocok dengan aturan yang paling jarang dicocokkan.
- Gunakan
skipRemainingRules: true
jika memungkinkan karena aturan yang cocok secara komputasi mahal dan meningkatkan waktu respons aplikasi. Lewati pemrosesan aturan yang tersisa ketika kecocokan terjadi dan tidak diperlukan pemrosesan aturan tambahan.
Peringatan
Pengguna berbahaya dapat memberikan input yang mahal untuk diproses hingga RegularExpressions
menyebabkan serangan Denial-of-Service. ASP.NET API kerangka kerja Core yang menggunakan RegularExpressions
batas waktu. Misalnya, kelas RedirectRule dan RewriteRule keduanya melewati batas waktu satu detik.
Apache mod_rewrite
Terapkan aturan Apache mod_rewrite dengan AddApacheModRewrite. Pastikan file aturan disebarkan dengan aplikasi. Untuk informasi selengkapnya dan contoh aturan mod_rewrite, lihat Apache mod_rewrite.
StreamReader digunakan untuk membaca aturan dari file aturan 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();
Aplikasi sampel mengalihkan permintaan dari /apache-mod-rules-redirect/(.\*)
ke /redirected?id=$1
. Kode status respons adalah 302 - Ditemukan.
# Rewrite path with additional sub directory
RewriteRule ^/apache-mod-rules-redirect/(.*) /redirected?id=$1 [L,R=302]
Coba permintaan ke https://redirect6.azurewebsites.net/apache-mod-rules-redirect/1234
Middleware Apache mendukung variabel server apache mod_rewrite berikut:
- 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
Aturan Modul Penulisan Ulang URL IIS
Untuk menggunakan seperangkat aturan yang sama yang berlaku untuk Modul Penulisan Ulang URL IIS, gunakan AddIISUrlRewrite. Pastikan file aturan disebarkan dengan aplikasi. Jangan arahkan middleware untuk menggunakan file web.config aplikasi saat berjalan di Windows Server IIS. Dengan IIS, aturan ini harus disimpan di luar file web.config aplikasi untuk menghindari konflik dengan modul Penulisan Ulang IIS. Untuk informasi selengkapnya dan contoh aturan Modul Penulisan Ulang URL IIS, lihat Menggunakan Modul Penulisan Ulang Url 2.0 dan Referensi Konfigurasi Modul Penulisan Ulang URL.
StreamReader digunakan untuk membaca aturan dari IISUrlRewrite.xml
file aturan:
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();
Aplikasi sampel menulis ulang permintaan dari /iis-rules-rewrite/(.*)
ke /rewritten?id=$1
. Respons dikirim ke klien dengan kode status 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>
Coba permintaan ke https://redirect6.azurewebsites.net/iis-rules-rewrite/xyz
Aplikasi yang memiliki Modul Penulisan Ulang IIS aktif dengan aturan tingkat server yang dikonfigurasi yang memengaruhi aplikasi dengan cara yang tidak diinginkan:
- Pertimbangkan untuk menonaktifkan Modul Penulisan Ulang IIS untuk aplikasi.
- Untuk informasi selengkapnya, lihat Menonaktifkan modul IIS.
Fitur yang tidak didukung
Middleware tidak mendukung fitur Modul Penulisan Ulang URL IIS berikut:
- Aturan Keluar
- Variabel Server Kustom
- Wildcard
- LogRewrittenUrl
Variabel server yang didukung
Middleware mendukung variabel server Modul Penulisan Ulang URL IIS berikut:
- 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 dapat diperoleh melalui PhysicalFileProvider. Pendekatan ini dapat memberikan fleksibilitas yang lebih besar untuk lokasi file aturan penulisan ulang. Pastikan bahwa file aturan penulisan ulang disebarkan ke server di jalur yang disediakan.
var fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());
Aturan berbasis metode
Gunakan Add untuk menerapkan logika aturan kustom dalam metode . Add
RewriteContextmengekspos , yang menyediakan HttpContext untuk digunakan dalam metode pengalihan. Properti RewriteContext.Result menentukan bagaimana pemrosesan alur tambahan ditangani. Atur nilai ke salah satu bidang yang RuleResult dijelaskan dalam tabel berikut ini.
Menulis ulang hasil konteks | Perbuatan |
---|---|
RuleResult.ContinueRules (default) |
Lanjutkan menerapkan aturan. |
RuleResult.EndResponse |
Berhenti menerapkan aturan dan kirim respons. |
RuleResult.SkipRemainingRules |
Berhenti menerapkan aturan dan kirim konteks ke middleware berikutnya. |
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();
Aplikasi sampel menunjukkan metode yang mengalihkan permintaan untuk jalur yang diakhir dengan .xml
. Ketika permintaan dibuat untuk /file.xml
:
- Permintaan dialihkan ke
/xmlfiles/file.xml
- Kode status diatur ke
301 - Moved Permanently
. Ketika browser membuat permintaan baru untuk/xmlfiles/file.xml
, Middleware File Statis melayani file ke klien dari folder wwwroot/xmlfiles . Untuk pengalihan, atur kode status respons secara eksplisit. Jika tidak, kode status 200 - OK dikembalikan, dan pengalihan tidak terjadi pada klien.
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;
}
}
Pendekatan ini juga dapat menulis ulang permintaan. Aplikasi sampel menunjukkan penulisan ulang jalur untuk permintaan file teks apa pun untuk melayani file teks file.txt dari folder wwwroot . Middleware File Statis melayani file berdasarkan jalur permintaan yang diperbarui:
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";
}
}
Aturan berbasis IRule
Gunakan Add untuk menggunakan logika aturan di kelas yang mengimplementasikan IRule antarmuka. IRule
memberikan fleksibilitas yang lebih besar daripada menggunakan pendekatan aturan berbasis metode. Kelas implementasi dapat mencakup konstruktor yang memungkinkan meneruskan parameter untuk metode .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();
Nilai parameter di aplikasi sampel untuk extension
dan newPath
diperiksa untuk memenuhi beberapa kondisi. extension
harus berisi nilai, dan nilainya harus .png
, , .jpg
atau .gif
. newPath
Jika tidak valid, maka ArgumentException akan dilemparkan. Jika permintaan dibuat untuk image.png
, permintaan dialihkan ke /png-images/image.png
. Jika permintaan dibuat untuk image.jpg
, permintaan dialihkan ke /jpg-images/image.jpg
. Kode status diatur ke 301 - Moved Permanently
, dan context.Result
diatur untuk menghentikan aturan pemrosesan dan mengirim respons.
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;
}
}
}
Coba:
- Permintaan PNG:
https://redirect6.azurewebsites.net/image.png
- Permintaan JPG:
https://redirect6.azurewebsites.net/image.jpg
Contoh regex
Goal | String Regex & Contoh Kecocokan |
String Penggantian & Contoh Output |
---|---|---|
Menulis ulang jalur ke dalam querystring | ^path/(.*)/(.*) /path/abc/123 |
path?var1=$1&var2=$2 /path?var1=abc&var2=123 |
Garis miring berikutnya | ^path2/(.*)/$ /path2/xyz/ |
$1 /path2/xyz |
Terapkan garis miring berikutnya | ^path3/(.*[^/])$ /path3/xyz |
$1/ /path3/xyz/ |
Hindari menulis ulang permintaan tertentu | ^(.*)(?<!\.axd)$ atau ^(?!.*\.axd$)(.*)$ Ya: /path4/resource.htm Tidak: /path4/resource.axd |
rewritten/$1 /rewritten/resource.htm /resource.axd |
Menyusun ulang segmen URL | path5/(.*)/(.*)/(.*) path5/1/2/3 |
path5/$3/$2/$1 path5/3/2/1 |
Mengganti segmen URL | ^path6/(.*)/segment2/(.*) ^path6/segment1/segment2/segment3 |
path6/$1/replaced/$2 /path6/segment1/replaced/segment3 |
Tautan dalam tabel sebelumnya menggunakan kode berikut yang disebarkan ke 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();
Di sebagian besar sampel ekspresi reguler sebelumnya, harfiah path
digunakan untuk membuat aturan penulisan ulang unik yang dapat diuji untuk sampel yang disebarkan. Biasanya ekspresi reguler tidak akan menyertakan path
. Misalnya, lihat tabel contoh ekspresi reguler ini.
Dokumen ini memperkenalkan penulisan ulang URL dengan instruksi tentang cara menggunakan URL Menulis Ulang Middleware di aplikasi ASP.NET Core.
Penulisan ulang URL adalah tindakan memodifikasi URL permintaan berdasarkan satu atau beberapa aturan yang telah ditentukan sebelumnya. Penulisan ulang URL membuat abstraksi antara lokasi sumber daya dan alamatnya sehingga lokasi dan alamat tidak ditautkan dengan erat. Penulisan ulang URL sangat berharga dalam beberapa skenario untuk:
- Pindahkan atau ganti sumber daya server untuk sementara atau permanen dan pertahankan pencari lokasi yang stabil untuk sumber daya tersebut.
- Memisahkan pemrosesan permintaan di berbagai aplikasi atau di seluruh area satu aplikasi.
- Menghapus, menambahkan, atau mengatur ulang segmen URL pada permintaan masuk.
- Optimalkan URL publik untuk Pengoptimalan Mesin Pencari (SEO).
- Izinkan penggunaan URL publik yang ramah untuk membantu pengunjung memprediksi konten yang dikembalikan dengan meminta sumber daya.
- Alihkan permintaan yang tidak aman ke titik akhir yang aman.
- Cegah hotlinking, di mana situs eksternal menggunakan aset statis yang dihosting di situs lain dengan menautkan aset ke kontennya sendiri.
Catatan
Penulisan ulang URL dapat mengurangi performa aplikasi. Jika memungkinkan, batasi jumlah dan kompleksitas aturan.
Melihat atau mengunduh kode sampel (cara mengunduh)
Pengalihan URL dan regenerasi URL
Perbedaan kata antara pengalihan URL dan penulisan ulang URL halus tetapi memiliki implikasi penting untuk menyediakan sumber daya kepada klien. ASP.NET Penulisan Ulang URL Core Middleware mampu memenuhi kebutuhan keduanya.
Pengalihan URL melibatkan operasi sisi klien, di mana klien diinstruksikan untuk mengakses sumber daya di alamat yang berbeda dari klien yang awalnya diminta. Ini memerlukan perjalanan pulang pergi ke server. URL pengalihan yang dikembalikan ke klien muncul di bilah alamat browser saat klien membuat permintaan baru untuk sumber daya.
Jika /resource
dialihkan ke /different-resource
, server merespons bahwa klien harus mendapatkan sumber daya di /different-resource
dengan kode status yang menunjukkan bahwa pengalihan bersifat sementara atau permanen.
Saat mengalihkan permintaan ke URL yang berbeda, tunjukkan apakah pengalihan bersifat permanen atau sementara dengan menentukan kode status dengan respons:
Kode
301 - Moved Permanently
status digunakan di mana sumber daya memiliki URL permanen baru dan Anda ingin menginstruksikan klien bahwa semua permintaan sumber daya di masa mendatang harus menggunakan URL baru. Klien dapat menyimpan dan menggunakan kembali respons saat kode status 301 diterima.Kode status 302 - Ditemukan digunakan di mana pengalihan bersifat sementara atau umumnya dapat berubah. Kode status 302 menunjukkan kepada klien untuk tidak menyimpan URL dan menggunakannya di masa mendatang.
Untuk informasi selengkapnya tentang kode status, lihat RFC 9110: Definisi Kode Status.
Penulisan ulang URL adalah operasi sisi server yang menyediakan sumber daya dari alamat sumber daya yang berbeda dari yang diminta klien. Menulis ulang URL tidak memerlukan perjalanan pulang pergi ke server. URL yang ditulis ulang tidak dikembalikan ke klien dan tidak muncul di bilah alamat browser.
Jika /resource
ditulis ulang ke /different-resource
, server secara internal mengambil dan mengembalikan sumber daya di /different-resource
.
Meskipun klien mungkin dapat mengambil sumber daya di URL yang ditulis ulang, klien tidak diberi tahu bahwa sumber daya ada di URL yang ditulis ulang saat membuat permintaannya dan menerima respons.
Aplikasi sampel penulisan ulang URL
Anda dapat menjelajahi fitur MIDDLEware Penulisan Ulang URL dengan aplikasi sampel. Aplikasi ini menerapkan aturan pengalihan dan penulisan ulang dan menunjukkan URL yang dialihkan atau ditulis ulang untuk beberapa skenario.
Kapan menggunakan middleware penulisan ulang URL
Gunakan Middleware Penulisan Ulang URL saat Anda tidak dapat menggunakan pendekatan berikut:
- Modul Penulisan Ulang URL dengan IIS di Windows Server
- Modul Apache mod_rewrite di Apache Server
- Penulisan ulang URL pada Nginx
Gunakan middleware penulisan ulang URL saat aplikasi dihosting di server HTTP.sys.
Alasan utama untuk menggunakan teknologi penulisan ulang URL berbasis server di IIS, Apache, dan Nginx adalah:
Middleware tidak mendukung fitur lengkap modul ini.
Beberapa fitur modul server tidak berfungsi dengan proyek ASP.NET Core, seperti
IsFile
batasan danIsDirectory
modul Penulisan Ulang IIS. Dalam skenario ini, gunakan middleware sebagai gantinya.Performa middleware mungkin tidak cocok dengan modul.
Tolok ukur adalah satu-satunya cara untuk mengetahui dengan pasti pendekatan mana yang paling banyak menurunkan performa atau jika performa yang terdegradasi dapat diabaikan.
Paket
Url Penulisan Ulang Middleware disediakan oleh paket Microsoft.AspNetCore.Rewrite , yang secara implisit disertakan dalam aplikasi ASP.NET Core.
Ekstensi dan opsi
Buat aturan penulisan ulang dan pengalihan URL dengan membuat instans kelas RewriteOptions dengan metode ekstensi untuk setiap aturan penulisan ulang Anda. Rantai beberapa aturan dalam urutan yang Anda inginkan untuk diproses. RewriteOptions
diteruskan ke URL Menulis Ulang Middleware saat ditambahkan ke alur permintaan dengan 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}"));
}
Mengalihkan non-www ke www
Tiga opsi mengizinkan aplikasi untuk mengalihkan permintaan non-kewww
www
:
AddRedirectToWwwPermanent: Alihkan permintaan secara permanen ke
www
subdomain jika permintaan non-www
. Pengalihan dengan kode status Status308PermanentRedirect .AddRedirectToWww: Alihkan permintaan ke
www
subdomain jika permintaan masuk non-www
. Pengalihan dengan kode status Status307TemporaryRedirect . Kelebihan beban memungkinkan Anda memberikan kode status untuk respons. Gunakan bidang StatusCodes kelas untuk penetapan kode status.
Pengalihan URL
Gunakan AddRedirect untuk mengalihkan permintaan. Parameter pertama berisi Regex Anda untuk pencocokan pada jalur URL masuk. Parameter kedua adalah string pengganti. Parameter ketiga, jika ada, menentukan kode status. Jika Anda tidak menentukan kode status, kode status default ke 302 - Ditemukan, yang menunjukkan bahwa sumber daya untuk sementara dipindahkan atau diganti.
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}"));
}
Di browser dengan alat pengembang diaktifkan, buat permintaan ke aplikasi sampel dengan jalur /redirect-rule/1234/5678
. Regex cocok dengan jalur permintaan pada redirect-rule/(.*)
, dan jalur diganti dengan /redirected/1234/5678
. URL pengalihan dikirim kembali ke klien dengan kode status 302 - Ditemukan . Browser membuat permintaan baru di URL pengalihan, yang muncul di bilah alamat browser. Karena tidak ada aturan dalam aplikasi sampel yang cocok pada URL pengalihan:
- Permintaan kedua menerima respons 200 - OK dari aplikasi.
- Isi respons menunjukkan URL pengalihan.
Perjalanan pulang pergi dilakukan ke server saat URL dialihkan.
Peringatan
Berhati-hatilah saat membuat aturan pengalihan. Aturan pengalihan dievaluasi pada setiap permintaan ke aplikasi, termasuk setelah pengalihan. Sangat mudah untuk secara tidak sengaja membuat perulangan pengalihan tak terbatas.
Permintaan Asli: /redirect-rule/1234/5678
Bagian dari ekspresi yang terkandung dalam tanda kurung disebut grup pengambilan. Titik (.
) ekspresi berarti cocok dengan karakter apa pun. Tanda bintang (*
) menunjukkan kecocokan nol karakter sebelumnya atau lebih kali. Oleh karena itu, dua segmen jalur terakhir URL, 1234/5678
, ditangkap oleh grup (.*)
pengambilan . Nilai apa pun yang Anda berikan dalam URL permintaan setelah redirect-rule/
diambil oleh grup tangkapan tunggal ini.
Dalam string pengganti, grup yang diambil disuntikkan ke dalam string dengan tanda dolar ($
) diikuti dengan nomor urut pengambilan. Nilai grup pengambilan pertama diperoleh dengan $1
, yang kedua dengan $2
, dan mereka melanjutkan secara berurutan untuk grup pengambilan di regex Anda. Hanya ada satu grup yang diambil dalam regex aturan pengalihan di aplikasi sampel, jadi hanya ada satu grup yang disuntikkan dalam string pengganti, yaitu $1
. Saat aturan diterapkan, URL menjadi /redirected/1234/5678
.
Pengalihan URL ke titik akhir yang aman
Gunakan AddRedirectToHttps untuk mengalihkan permintaan HTTP ke host dan jalur yang sama menggunakan protokol HTTPS. Jika kode status tidak disediakan, middleware default ke 302 - Ditemukan. Jika port tidak disediakan:
- Middleware default ke
null
. - Skema berubah menjadi
https
(protokol HTTPS), dan klien mengakses sumber daya pada port 443.
Contoh berikut menunjukkan cara mengatur kode status ke 301 - Moved Permanently
dan mengubah port menjadi 5001.
public void Configure(IApplicationBuilder app)
{
var options = new RewriteOptions()
.AddRedirectToHttps(301, 5001);
app.UseRewriter(options);
}
Gunakan AddRedirectToHttpsPermanent untuk mengalihkan permintaan yang tidak aman ke host dan jalur yang sama dengan protokol HTTPS aman pada port 443. Middleware mengatur kode status ke 301 - Moved Permanently
.
public void Configure(IApplicationBuilder app)
{
var options = new RewriteOptions()
.AddRedirectToHttpsPermanent();
app.UseRewriter(options);
}
Catatan
Saat mengalihkan ke titik akhir yang aman tanpa persyaratan untuk aturan pengalihan tambahan, sebaiknya gunakan Middleware Pengalihan HTTPS. Untuk informasi selengkapnya, lihat topik Terlaksanakan HTTPS .
Aplikasi sampel mampu menunjukkan cara menggunakan AddRedirectToHttps
atau AddRedirectToHttpsPermanent
. Tambahkan metode ekstensi ke RewriteOptions
. Buat permintaan yang tidak aman ke aplikasi di URL apa pun. Mengabaikan peringatan keamanan browser bahwa sertifikat yang ditandatangani sendiri tidak tepercaya atau membuat pengecualian untuk mempercayai sertifikat.
Permintaan Asli menggunakan AddRedirectToHttps(301, 5001)
: http://localhost:5000/secure
Permintaan Asli menggunakan AddRedirectToHttpsPermanent
: http://localhost:5000/secure
Penulisan ulang URL
Gunakan AddRewrite untuk membuat aturan untuk menulis ulang URL. Parameter pertama berisi regex untuk pencocokan pada jalur URL masuk. Parameter kedua adalah string pengganti. Parameter ketiga, skipRemainingRules: {true|false}
, menunjukkan kepada middleware apakah akan melewati aturan penulisan ulang tambahan atau tidak jika aturan saat ini diterapkan.
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}"));
}
Permintaan Asli: /rewrite-rule/1234/5678
Karat (^
) di awal ekspresi berarti bahwa pencocokan dimulai di awal jalur URL.
Dalam contoh sebelumnya dengan aturan pengalihan, redirect-rule/(.*)
, tidak ada karat (^
) di awal regex. Oleh karena itu, setiap karakter dapat mendahului redirect-rule/
di jalur untuk kecocokan yang berhasil.
Jalur | Cocokkan |
---|---|
/redirect-rule/1234/5678 |
Ya |
/my-cool-redirect-rule/1234/5678 |
Ya |
/anotherredirect-rule/1234/5678 |
Ya |
Aturan penulisan ulang, ^rewrite-rule/(\d+)/(\d+)
, hanya cocok dengan jalur jika dimulai dengan rewrite-rule/
. Dalam tabel berikut, perhatikan perbedaan dalam pencocokan.
Jalur | Cocokkan |
---|---|
/rewrite-rule/1234/5678 |
Ya |
/my-cool-rewrite-rule/1234/5678 |
No |
/anotherrewrite-rule/1234/5678 |
Tidak |
^rewrite-rule/
Setelah bagian ekspresi, ada dua grup pengambilan, (\d+)/(\d+)
. Menandakan \d
cocok dengan digit (angka). Tanda plus (+
) berarti cocok dengan satu atau beberapa karakter sebelumnya. Oleh karena itu, URL harus berisi angka yang diikuti dengan garis miring diikuti dengan angka lain. Grup penangkapan ini disuntikkan ke DALAM URL yang ditulis ulang sebagai $1
dan $2
. String penggantian aturan penulisan ulang menempatkan grup yang diambil ke dalam string kueri. Jalur /rewrite-rule/1234/5678
yang diminta ditulis ulang untuk mendapatkan sumber daya di /rewritten?var1=1234&var2=5678
. Jika string kueri ada pada permintaan asli, string tersebut dipertahankan saat URL ditulis ulang.
Tidak ada perjalanan pulang pergi ke server untuk mendapatkan sumber daya. Jika sumber daya ada, sumber daya diambil dan dikembalikan ke klien dengan kode status 200 - OK . Karena klien tidak dialihkan, URL di bilah alamat browser tidak berubah. Klien tidak dapat mendeteksi bahwa operasi penulisan ulang URL terjadi di server.
Catatan
Gunakan skipRemainingRules: true
jika memungkinkan karena aturan yang cocok secara komputasi mahal dan meningkatkan waktu respons aplikasi. Untuk respons aplikasi tercepat:
- Aturan penulisan ulang pesanan dari aturan yang paling sering cocok dengan aturan yang paling jarang dicocokkan.
- Lewati pemrosesan aturan yang tersisa ketika kecocokan terjadi dan tidak diperlukan pemrosesan aturan tambahan.
Apache mod_rewrite
Terapkan aturan Apache mod_rewrite dengan AddApacheModRewrite. Pastikan file aturan disebarkan dengan aplikasi. Untuk informasi selengkapnya dan contoh aturan mod_rewrite, lihat Apache mod_rewrite.
StreamReader digunakan untuk membaca aturan dari file aturan 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}"));
}
Aplikasi sampel mengalihkan permintaan dari /apache-mod-rules-redirect/(.\*)
ke /redirected?id=$1
. Kode status respons adalah 302 - Ditemukan.
# Rewrite path with additional sub directory
RewriteRule ^/apache-mod-rules-redirect/(.*) /redirected?id=$1 [L,R=302]
Permintaan Asli: /apache-mod-rules-redirect/1234
Middleware mendukung variabel server Apache mod_rewrite berikut:
- 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
Aturan Modul Penulisan Ulang URL IIS
Untuk menggunakan seperangkat aturan yang sama yang berlaku untuk Modul Penulisan Ulang URL IIS, gunakan AddIISUrlRewrite. Pastikan file aturan disebarkan dengan aplikasi. Jangan arahkan middleware untuk menggunakan file web.config aplikasi saat berjalan di Windows Server IIS. Dengan IIS, aturan ini harus disimpan di luar file web.config aplikasi untuk menghindari konflik dengan modul Penulisan Ulang IIS. Untuk informasi selengkapnya dan contoh aturan Modul Penulisan Ulang URL IIS, lihat Menggunakan Modul Penulisan Ulang Url 2.0 dan Referensi Konfigurasi Modul Penulisan Ulang URL.
StreamReader digunakan untuk membaca aturan dari IISUrlRewrite.xml
file aturan:
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}"));
}
Aplikasi sampel menulis ulang permintaan dari /iis-rules-rewrite/(.*)
ke /rewritten?id=$1
. Respons dikirim ke klien dengan kode status 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>
Permintaan Asli: /iis-rules-rewrite/1234
Jika Anda memiliki Modul Penulisan Ulang IIS aktif dengan aturan tingkat server yang dikonfigurasi yang akan memengaruhi aplikasi Anda dengan cara yang tidak diinginkan, Anda dapat menonaktifkan Modul Penulisan Ulang IIS untuk aplikasi. Untuk informasi selengkapnya, lihat Menonaktifkan modul IIS.
Fitur yang tidak didukung
Middleware tidak mendukung fitur Modul Penulisan Ulang URL IIS berikut:
- Aturan Keluar
- Variabel Server Kustom
- Wildcard
- LogRewrittenUrl
Variabel server yang didukung
Middleware mendukung variabel server Modul Penulisan Ulang URL IIS berikut:
- 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
Catatan
Anda juga dapat memperoleh IFileProvider melalui PhysicalFileProvider. Pendekatan ini dapat memberikan fleksibilitas yang lebih besar untuk lokasi file aturan penulisan ulang Anda. Pastikan file aturan penulisan ulang Anda disebarkan ke server di jalur yang Anda sediakan.
PhysicalFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());
Aturan berbasis metode
Gunakan Add untuk menerapkan logika aturan Anda sendiri dalam metode . Add
RewriteContextmengekspos , yang menyediakan HttpContext untuk digunakan dalam metode Anda. RewriteContext.Result menentukan bagaimana pemrosesan alur tambahan ditangani. Atur nilai ke salah satu bidang yang RuleResult dijelaskan dalam tabel berikut ini.
Menulis ulang hasil konteks | Perbuatan |
---|---|
RuleResult.ContinueRules (default) |
Lanjutkan menerapkan aturan. |
RuleResult.EndResponse |
Berhenti menerapkan aturan dan kirim respons. |
RuleResult.SkipRemainingRules |
Berhenti menerapkan aturan dan kirim konteks ke middleware berikutnya. |
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}"));
}
Aplikasi sampel menunjukkan metode yang mengalihkan permintaan untuk jalur yang diakhir dengan .xml
. Jika permintaan dibuat untuk /file.xml
, permintaan dialihkan ke /xmlfiles/file.xml
. Kode status diatur ke 301 - Moved Permanently
. Ketika browser membuat permintaan baru untuk /xmlfiles/file.xml
, Middleware File Statis melayani file ke klien dari folder wwwroot/xmlfiles . Untuk pengalihan, atur kode status respons secara eksplisit. Jika tidak, kode status 200 - OK dikembalikan, dan pengalihan tidak terjadi pada klien.
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;
}
}
Pendekatan ini juga dapat menulis ulang permintaan. Aplikasi sampel menunjukkan penulisan ulang jalur untuk permintaan file teks apa pun untuk melayani file teks file.txt dari folder wwwroot . Middleware File Statis melayani file berdasarkan jalur permintaan yang diperbarui:
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";
}
}
Aturan berbasis IRule
Gunakan Add untuk menggunakan logika aturan di kelas yang mengimplementasikan IRule antarmuka. IRule
memberikan fleksibilitas yang lebih besar daripada menggunakan pendekatan aturan berbasis metode. Kelas implementasi Anda dapat mencakup konstruktor yang memungkinkan Anda dapat meneruskan parameter untuk metode tersebut 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}"));
}
Nilai parameter di aplikasi sampel untuk extension
dan newPath
diperiksa untuk memenuhi beberapa kondisi. extension
harus berisi nilai, dan nilainya harus .png
, , .jpg
atau .gif. newPath
Jika tidak valid, maka ArgumentException akan dilemparkan. Jika permintaan dibuat untuk image.png
, permintaan dialihkan ke /png-images/image.png
. Jika permintaan dibuat untuk image.jpg
, permintaan dialihkan ke /jpg-images/image.jpg
. Kode status diatur ke 301 - Moved Permanently
, dan context.Result
diatur untuk menghentikan aturan pemrosesan dan mengirim respons.
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;
}
}
}
Permintaan Asli: /image.png
Permintaan Asli: /image.jpg
Contoh regex
Goal | String Regex & Contoh Kecocokan |
String Penggantian & Contoh Output |
---|---|---|
Menulis ulang jalur ke dalam querystring | ^path/(.*)/(.*) /path/abc/123 |
path?var1=$1&var2=$2 /path?var1=abc&var2=123 |
Garis miring berikutnya | (.*)/$ /path/ |
$1 /path |
Terapkan garis miring berikutnya | (.*[^/])$ /path |
$1/ /path/ |
Hindari menulis ulang permintaan tertentu | ^(.*)(?<!\.axd)$ atau ^(?!.*\.axd$)(.*)$ Ya: /resource.htm Tidak: /resource.axd |
rewritten/$1 /rewritten/resource.htm /resource.axd |
Menyusun ulang segmen URL | path/(.*)/(.*)/(.*) path/1/2/3 |
path/$3/$2/$1 path/3/2/1 |
Mengganti segmen URL | ^(.*)/segment2/(.*) /segment1/segment2/segment3 |
$1/replaced/$2 /segment1/replaced/segment3 |
Dokumen ini memperkenalkan penulisan ulang URL dengan instruksi tentang cara menggunakan URL Menulis Ulang Middleware di aplikasi ASP.NET Core.
Penulisan ulang URL adalah tindakan memodifikasi URL permintaan berdasarkan satu atau beberapa aturan yang telah ditentukan sebelumnya. Penulisan ulang URL membuat abstraksi antara lokasi sumber daya dan alamatnya sehingga lokasi dan alamat tidak ditautkan dengan erat. Penulisan ulang URL sangat berharga dalam beberapa skenario untuk:
- Pindahkan atau ganti sumber daya server untuk sementara atau permanen dan pertahankan pencari lokasi yang stabil untuk sumber daya tersebut.
- Memisahkan pemrosesan permintaan di berbagai aplikasi atau di seluruh area satu aplikasi.
- Menghapus, menambahkan, atau mengatur ulang segmen URL pada permintaan masuk.
- Optimalkan URL publik untuk Pengoptimalan Mesin Pencari (SEO).
- Izinkan penggunaan URL publik yang ramah untuk membantu pengunjung memprediksi konten yang dikembalikan dengan meminta sumber daya.
- Alihkan permintaan yang tidak aman ke titik akhir yang aman.
- Cegah hotlinking, di mana situs eksternal menggunakan aset statis yang dihosting di situs lain dengan menautkan aset ke kontennya sendiri.
Catatan
Penulisan ulang URL dapat mengurangi performa aplikasi. Jika memungkinkan, batasi jumlah dan kompleksitas aturan.
Melihat atau mengunduh kode sampel (cara mengunduh)
Pengalihan URL dan regenerasi URL
Perbedaan kata antara pengalihan URL dan penulisan ulang URL halus tetapi memiliki implikasi penting untuk menyediakan sumber daya kepada klien. ASP.NET Penulisan Ulang URL Core Middleware mampu memenuhi kebutuhan keduanya.
Pengalihan URL melibatkan operasi sisi klien, di mana klien diinstruksikan untuk mengakses sumber daya di alamat yang berbeda dari klien yang awalnya diminta. Ini memerlukan perjalanan pulang pergi ke server. URL pengalihan yang dikembalikan ke klien muncul di bilah alamat browser saat klien membuat permintaan baru untuk sumber daya.
Jika /resource
dialihkan ke /different-resource
, server merespons bahwa klien harus mendapatkan sumber daya di /different-resource
dengan kode status yang menunjukkan bahwa pengalihan bersifat sementara atau permanen.
Saat mengalihkan permintaan ke URL yang berbeda, tunjukkan apakah pengalihan bersifat permanen atau sementara dengan menentukan kode status dengan respons:
Kode
301 - Moved Permanently
status digunakan di mana sumber daya memiliki URL permanen baru dan Anda ingin menginstruksikan klien bahwa semua permintaan sumber daya di masa mendatang harus menggunakan URL baru. Klien dapat menyimpan dan menggunakan kembali respons saat kode status 301 diterima.Kode status 302 - Ditemukan digunakan di mana pengalihan bersifat sementara atau umumnya dapat berubah. Kode status 302 menunjukkan kepada klien untuk tidak menyimpan URL dan menggunakannya di masa mendatang.
Untuk informasi selengkapnya tentang kode status, lihat RFC 9110: Definisi Kode Status.
Penulisan ulang URL adalah operasi sisi server yang menyediakan sumber daya dari alamat sumber daya yang berbeda dari yang diminta klien. Menulis ulang URL tidak memerlukan perjalanan pulang pergi ke server. URL yang ditulis ulang tidak dikembalikan ke klien dan tidak muncul di bilah alamat browser.
Jika /resource
ditulis ulang ke /different-resource
, server secara internal mengambil dan mengembalikan sumber daya di /different-resource
.
Meskipun klien mungkin dapat mengambil sumber daya di URL yang ditulis ulang, klien tidak diberi tahu bahwa sumber daya ada di URL yang ditulis ulang saat membuat permintaannya dan menerima respons.
Aplikasi sampel penulisan ulang URL
Anda dapat menjelajahi fitur MIDDLEware Penulisan Ulang URL dengan aplikasi sampel. Aplikasi ini menerapkan aturan pengalihan dan penulisan ulang dan menunjukkan URL yang dialihkan atau ditulis ulang untuk beberapa skenario.
Kapan menggunakan MIDDLEware Penulisan Ulang URL
Gunakan Middleware Penulisan Ulang URL saat Anda tidak dapat menggunakan pendekatan berikut:
- Modul Penulisan Ulang URL dengan IIS di Windows Server
- Modul Apache mod_rewrite di Apache Server
- Penulisan ulang URL pada Nginx
Selain itu, gunakan middleware saat aplikasi dihosting di server HTTP.sys (sebelumnya disebut WebListener).
Alasan utama untuk menggunakan teknologi penulisan ulang URL berbasis server di IIS, Apache, dan Nginx adalah:
Middleware tidak mendukung fitur lengkap modul ini.
Beberapa fitur modul server tidak berfungsi dengan proyek ASP.NET Core, seperti
IsFile
batasan danIsDirectory
modul Penulisan Ulang IIS. Dalam skenario ini, gunakan middleware sebagai gantinya.Performa middleware mungkin tidak cocok dengan modul.
Tolok ukur adalah satu-satunya cara untuk mengetahui dengan pasti pendekatan mana yang paling banyak menurunkan performa atau jika performa yang terdegradasi dapat diabaikan.
Paket
Untuk menyertakan middleware dalam proyek Anda, tambahkan referensi paket ke metapackage Microsoft.AspNetCore.App dalam file proyek, yang berisi paket Microsoft.AspNetCore.Rewrite .
Saat tidak menggunakan Microsoft.AspNetCore.App
metapackage, tambahkan referensi proyek ke Microsoft.AspNetCore.Rewrite
paket.
Ekstensi dan opsi
Buat aturan penulisan ulang dan pengalihan URL dengan membuat instans kelas RewriteOptions dengan metode ekstensi untuk setiap aturan penulisan ulang Anda. Rantai beberapa aturan dalam urutan yang Anda inginkan untuk diproses. RewriteOptions
diteruskan ke URL Menulis Ulang Middleware saat ditambahkan ke alur permintaan dengan 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}"));
}
Mengalihkan non-www ke www
Tiga opsi mengizinkan aplikasi untuk mengalihkan permintaan non-kewww
www
:
AddRedirectToWwwPermanent: Alihkan permintaan secara permanen ke
www
subdomain jika permintaan non-www
. Pengalihan dengan kode status Status308PermanentRedirect .AddRedirectToWww: Alihkan permintaan ke
www
subdomain jika permintaan masuk non-www
. Pengalihan dengan kode status Status307TemporaryRedirect . Kelebihan beban memungkinkan Anda memberikan kode status untuk respons. Gunakan bidang StatusCodes kelas untuk penetapan kode status.
Pengalihan URL
Gunakan AddRedirect untuk mengalihkan permintaan. Parameter pertama berisi regex Anda untuk pencocokan pada jalur URL masuk. Parameter kedua adalah string pengganti. Parameter ketiga, jika ada, menentukan kode status. Jika Anda tidak menentukan kode status, kode status default ke 302 - Ditemukan, yang menunjukkan bahwa sumber daya untuk sementara dipindahkan atau diganti.
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}"));
}
Di browser dengan alat pengembang diaktifkan, buat permintaan ke aplikasi sampel dengan jalur /redirect-rule/1234/5678
. Regex cocok dengan jalur permintaan pada redirect-rule/(.*)
, dan jalur diganti dengan /redirected/1234/5678
. URL pengalihan dikirim kembali ke klien dengan kode status 302 - Ditemukan . Browser membuat permintaan baru di URL pengalihan, yang muncul di bilah alamat browser. Karena tidak ada aturan dalam aplikasi sampel yang cocok pada URL pengalihan:
- Permintaan kedua menerima respons 200 - OK dari aplikasi.
- Isi respons menunjukkan URL pengalihan.
Perjalanan pulang pergi dilakukan ke server saat URL dialihkan.
Peringatan
Berhati-hatilah saat membuat aturan pengalihan. Aturan pengalihan dievaluasi pada setiap permintaan ke aplikasi, termasuk setelah pengalihan. Sangat mudah untuk secara tidak sengaja membuat perulangan pengalihan tak terbatas.
Permintaan Asli: /redirect-rule/1234/5678
Bagian dari ekspresi yang terkandung dalam tanda kurung disebut grup pengambilan. Titik (.
) ekspresi berarti cocok dengan karakter apa pun. Tanda bintang (*
) menunjukkan kecocokan nol karakter sebelumnya atau lebih kali. Oleh karena itu, dua segmen jalur terakhir URL, 1234/5678
, ditangkap oleh grup (.*)
pengambilan . Nilai apa pun yang Anda berikan dalam URL permintaan setelah redirect-rule/
diambil oleh grup tangkapan tunggal ini.
Dalam string pengganti, grup yang diambil disuntikkan ke dalam string dengan tanda dolar ($
) diikuti dengan nomor urut pengambilan. Nilai grup pengambilan pertama diperoleh dengan $1
, yang kedua dengan $2
, dan mereka melanjutkan secara berurutan untuk grup pengambilan di regex Anda. Hanya ada satu grup yang diambil dalam regex aturan pengalihan di aplikasi sampel, jadi hanya ada satu grup yang disuntikkan dalam string pengganti, yaitu $1
. Saat aturan diterapkan, URL menjadi /redirected/1234/5678
.
Pengalihan URL ke titik akhir yang aman
Gunakan AddRedirectToHttps untuk mengalihkan permintaan HTTP ke host dan jalur yang sama menggunakan protokol HTTPS. Jika kode status tidak disediakan, middleware default ke 302 - Ditemukan. Jika port tidak disediakan:
- Middleware default ke
null
. - Skema berubah menjadi
https
(protokol HTTPS), dan klien mengakses sumber daya pada port 443.
Contoh berikut menunjukkan cara mengatur kode status ke 301 - Moved Permanently
dan mengubah port menjadi 5001.
public void Configure(IApplicationBuilder app)
{
var options = new RewriteOptions()
.AddRedirectToHttps(301, 5001);
app.UseRewriter(options);
}
Gunakan AddRedirectToHttpsPermanent untuk mengalihkan permintaan yang tidak aman ke host dan jalur yang sama dengan protokol HTTPS aman pada port 443. Middleware mengatur kode status ke 301 - Moved Permanently
.
public void Configure(IApplicationBuilder app)
{
var options = new RewriteOptions()
.AddRedirectToHttpsPermanent();
app.UseRewriter(options);
}
Catatan
Saat mengalihkan ke titik akhir yang aman tanpa persyaratan untuk aturan pengalihan tambahan, sebaiknya gunakan Middleware Pengalihan HTTPS. Untuk informasi selengkapnya, lihat topik Terlaksanakan HTTPS .
Aplikasi sampel mampu menunjukkan cara menggunakan AddRedirectToHttps
atau AddRedirectToHttpsPermanent
. Tambahkan metode ekstensi ke RewriteOptions
. Buat permintaan yang tidak aman ke aplikasi di URL apa pun. Mengabaikan peringatan keamanan browser bahwa sertifikat yang ditandatangani sendiri tidak tepercaya atau membuat pengecualian untuk mempercayai sertifikat.
Permintaan Asli menggunakan AddRedirectToHttps(301, 5001)
: http://localhost:5000/secure
Permintaan Asli menggunakan AddRedirectToHttpsPermanent
: http://localhost:5000/secure
Penulisan ulang URL
Gunakan AddRewrite untuk membuat aturan untuk menulis ulang URL. Parameter pertama berisi regex untuk pencocokan pada jalur URL masuk. Parameter kedua adalah string pengganti. Parameter ketiga, skipRemainingRules: {true|false}
, menunjukkan kepada middleware apakah akan melewati aturan penulisan ulang tambahan atau tidak jika aturan saat ini diterapkan.
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}"));
}
Permintaan Asli: /rewrite-rule/1234/5678
Karat (^
) di awal ekspresi berarti bahwa pencocokan dimulai di awal jalur URL.
Dalam contoh sebelumnya dengan aturan pengalihan, redirect-rule/(.*)
, tidak ada karat (^
) di awal regex. Oleh karena itu, setiap karakter dapat mendahului redirect-rule/
di jalur untuk kecocokan yang berhasil.
Jalur | Cocokkan |
---|---|
/redirect-rule/1234/5678 |
Ya |
/my-cool-redirect-rule/1234/5678 |
Ya |
/anotherredirect-rule/1234/5678 |
Ya |
Aturan penulisan ulang, ^rewrite-rule/(\d+)/(\d+)
, hanya cocok dengan jalur jika dimulai dengan rewrite-rule/
. Dalam tabel berikut, perhatikan perbedaan dalam pencocokan.
Jalur | Cocokkan |
---|---|
/rewrite-rule/1234/5678 |
Ya |
/my-cool-rewrite-rule/1234/5678 |
No |
/anotherrewrite-rule/1234/5678 |
Tidak |
^rewrite-rule/
Setelah bagian ekspresi, ada dua grup pengambilan, (\d+)/(\d+)
. Menandakan \d
cocok dengan digit (angka). Tanda plus (+
) berarti cocok dengan satu atau beberapa karakter sebelumnya. Oleh karena itu, URL harus berisi angka yang diikuti dengan garis miring diikuti dengan angka lain. Grup penangkapan ini disuntikkan ke DALAM URL yang ditulis ulang sebagai $1
dan $2
. String penggantian aturan penulisan ulang menempatkan grup yang diambil ke dalam string kueri. Jalur /rewrite-rule/1234/5678
yang diminta ditulis ulang untuk mendapatkan sumber daya di /rewritten?var1=1234&var2=5678
. Jika string kueri ada pada permintaan asli, string tersebut dipertahankan saat URL ditulis ulang.
Tidak ada perjalanan pulang pergi ke server untuk mendapatkan sumber daya. Jika sumber daya ada, sumber daya diambil dan dikembalikan ke klien dengan kode status 200 - OK . Karena klien tidak dialihkan, URL di bilah alamat browser tidak berubah. Klien tidak dapat mendeteksi bahwa operasi penulisan ulang URL terjadi di server.
Catatan
Gunakan skipRemainingRules: true
jika memungkinkan karena aturan yang cocok secara komputasi mahal dan meningkatkan waktu respons aplikasi. Untuk respons aplikasi tercepat:
- Aturan penulisan ulang pesanan dari aturan yang paling sering cocok dengan aturan yang paling jarang dicocokkan.
- Lewati pemrosesan aturan yang tersisa ketika kecocokan terjadi dan tidak diperlukan pemrosesan aturan tambahan.
Apache mod_rewrite
Terapkan aturan Apache mod_rewrite dengan AddApacheModRewrite. Pastikan file aturan disebarkan dengan aplikasi. Untuk informasi selengkapnya dan contoh aturan mod_rewrite, lihat Apache mod_rewrite.
StreamReader digunakan untuk membaca aturan dari file aturan 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}"));
}
Aplikasi sampel mengalihkan permintaan dari /apache-mod-rules-redirect/(.\*)
ke /redirected?id=$1
. Kode status respons adalah 302 - Ditemukan.
# Rewrite path with additional sub directory
RewriteRule ^/apache-mod-rules-redirect/(.*) /redirected?id=$1 [L,R=302]
Permintaan Asli: /apache-mod-rules-redirect/1234
Middleware mendukung variabel server Apache mod_rewrite berikut:
- 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
Aturan Modul Penulisan Ulang URL IIS
Untuk menggunakan seperangkat aturan yang sama yang berlaku untuk Modul Penulisan Ulang URL IIS, gunakan AddIISUrlRewrite. Pastikan file aturan disebarkan dengan aplikasi. Jangan arahkan middleware untuk menggunakan file web.config aplikasi saat berjalan di Windows Server IIS. Dengan IIS, aturan ini harus disimpan di luar file web.config aplikasi untuk menghindari konflik dengan modul Penulisan Ulang IIS. Untuk informasi selengkapnya dan contoh aturan Modul Penulisan Ulang URL IIS, lihat Menggunakan Modul Penulisan Ulang Url 2.0 dan Referensi Konfigurasi Modul Penulisan Ulang URL.
StreamReader digunakan untuk membaca aturan dari IISUrlRewrite.xml
file aturan:
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}"));
}
Aplikasi sampel menulis ulang permintaan dari /iis-rules-rewrite/(.*)
ke /rewritten?id=$1
. Respons dikirim ke klien dengan kode status 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>
Permintaan Asli: /iis-rules-rewrite/1234
Jika Anda memiliki Modul Penulisan Ulang IIS aktif dengan aturan tingkat server yang dikonfigurasi yang akan memengaruhi aplikasi Anda dengan cara yang tidak diinginkan, Anda dapat menonaktifkan Modul Penulisan Ulang IIS untuk aplikasi. Untuk informasi selengkapnya, lihat Menonaktifkan modul IIS.
Fitur yang tidak didukung
Middleware yang dirilis dengan ASP.NET Core 2.x tidak mendukung fitur Modul Penulisan Ulang URL IIS berikut:
- Aturan Keluar
- Variabel Server Kustom
- Wildcard
- LogRewrittenUrl
Variabel server yang didukung
Middleware mendukung variabel server Modul Penulisan Ulang URL IIS berikut:
- 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
Catatan
Anda juga dapat memperoleh IFileProvider melalui PhysicalFileProvider. Pendekatan ini dapat memberikan fleksibilitas yang lebih besar untuk lokasi file aturan penulisan ulang Anda. Pastikan file aturan penulisan ulang Anda disebarkan ke server di jalur yang Anda sediakan.
PhysicalFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());
Aturan berbasis metode
Gunakan Add untuk menerapkan logika aturan Anda sendiri dalam metode . Add
RewriteContextmengekspos , yang menyediakan HttpContext untuk digunakan dalam metode Anda. RewriteContext.Result menentukan bagaimana pemrosesan alur tambahan ditangani. Atur nilai ke salah satu bidang yang RuleResult dijelaskan dalam tabel berikut ini.
Menulis ulang hasil konteks | Perbuatan |
---|---|
RuleResult.ContinueRules (default) |
Lanjutkan menerapkan aturan. |
RuleResult.EndResponse |
Berhenti menerapkan aturan dan kirim respons. |
RuleResult.SkipRemainingRules |
Berhenti menerapkan aturan dan kirim konteks ke middleware berikutnya. |
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}"));
}
Aplikasi sampel menunjukkan metode yang mengalihkan permintaan untuk jalur yang diakhir dengan .xml
. Jika permintaan dibuat untuk /file.xml
, permintaan dialihkan ke /xmlfiles/file.xml
. Kode status diatur ke 301 - Moved Permanently
. Ketika browser membuat permintaan baru untuk /xmlfiles/file.xml
, Middleware File Statis melayani file ke klien dari folder wwwroot/xmlfiles . Untuk pengalihan, atur kode status respons secara eksplisit. Jika tidak, kode status 200 - OK dikembalikan, dan pengalihan tidak terjadi pada klien.
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;
}
}
Pendekatan ini juga dapat menulis ulang permintaan. Aplikasi sampel menunjukkan penulisan ulang jalur untuk permintaan file teks apa pun untuk melayani file teks file.txt dari folder wwwroot . Middleware File Statis melayani file berdasarkan jalur permintaan yang diperbarui:
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";
}
}
Aturan berbasis IRule
Gunakan Add untuk menggunakan logika aturan di kelas yang mengimplementasikan IRule antarmuka. IRule
memberikan fleksibilitas yang lebih besar daripada menggunakan pendekatan aturan berbasis metode. Kelas implementasi Anda dapat mencakup konstruktor yang memungkinkan Anda dapat meneruskan parameter untuk metode tersebut 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}"));
}
Nilai parameter di aplikasi sampel untuk extension
dan newPath
diperiksa untuk memenuhi beberapa kondisi. extension
harus berisi nilai, dan nilainya harus .png
, , .jpg
atau .gif. newPath
Jika tidak valid, maka ArgumentException akan dilemparkan. Jika permintaan dibuat untuk image.png
, permintaan dialihkan ke /png-images/image.png
. Jika permintaan dibuat untuk image.jpg
, permintaan dialihkan ke /jpg-images/image.jpg
. Kode status diatur ke 301 - Moved Permanently
, dan context.Result
diatur untuk menghentikan aturan pemrosesan dan mengirim respons.
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;
}
}
}
Permintaan Asli: /image.png
Permintaan Asli: /image.jpg
Contoh regex
Goal | String Regex & Contoh Kecocokan |
String Penggantian & Contoh Output |
---|---|---|
Menulis ulang jalur ke dalam querystring | ^path/(.*)/(.*) /path/abc/123 |
path?var1=$1&var2=$2 /path?var1=abc&var2=123 |
Garis miring berikutnya | (.*)/$ /path/ |
$1 /path |
Terapkan garis miring berikutnya | (.*[^/])$ /path |
$1/ /path/ |
Hindari menulis ulang permintaan tertentu | ^(.*)(?<!\.axd)$ atau ^(?!.*\.axd$)(.*)$ Ya: /resource.htm Tidak: /resource.axd |
rewritten/$1 /rewritten/resource.htm /resource.axd |
Menyusun ulang segmen URL | path/(.*)/(.*)/(.*) path/1/2/3 |
path/$3/$2/$1 path/3/2/1 |
Mengganti segmen URL | ^(.*)/segment2/(.*) /segment1/segment2/segment3 |
$1/replaced/$2 /segment1/replaced/segment3 |
Sumber Daya Tambahan:
- Melihat atau mengunduh kode sampel (cara mengunduh)
- Sumber RewriteMiddleware di GitHub
- Startup aplikasi di ASP.NET Core
- ASP.NET Core Middleware
- Ekspresi reguler dalam .NET
- Bahasa regex - referensi cepat
- Apache mod_rewrite
- Menggunakan Modul Penulisan Ulang Url 2.0 (untuk IIS)
- Referensi Konfigurasi Modul Penulisan Ulang URL
- Pertahankan struktur URL sederhana
- 10 Tips dan Trik Penulisan Ulang URL
- Untuk menyortir atau tidak menyortir
ASP.NET Core