URLPattern menghadirkan pemilihan rute ke platform web

Pendekatan untuk menstandardisasi kasus penggunaan pencocokan pola umum.

Latar belakang

{i>Routing<i} adalah bagian penting dari setiap aplikasi web. Pada intinya, pemilihan rute melibatkan pengambilan URL, menerapkan beberapa pencocokan pola atau logika khusus aplikasi lainnya ke URL tersebut, lalu biasanya menampilkan konten web berdasarkan hasilnya. Perutean dapat diimplementasikan dengan beberapa cara: terkadang berupa kode yang berjalan di server yang memetakan jalur ke file pada disk, atau logika di aplikasi satu halaman yang menunggu perubahan pada lokasi saat ini dan membuat bagian DOM yang sesuai untuk ditampilkan.

Meskipun tidak ada standar pasti, developer web lebih memilih sintaksis umum untuk mengekspresikan pola pemilihan rute URL yang memiliki banyak kesamaan dengan regular expressions, tetapi dengan beberapa penambahan khusus domain seperti token untuk segmen jalur yang cocok. Framework sisi server populer seperti Express dan Ruby on Rails menggunakan sintaksis ini (atau yang sangat mirip dengannya), dan developer JavaScript dapat menggunakan modul seperti path-to-regexp atau regexpparam untuk menambahkan logika tersebut ke kode mereka sendiri.

URLPattern adalah tambahan untuk platform web yang dibangun berdasarkan fondasi yang dibuat oleh framework ini. Tujuannya adalah untuk menstandarkan sintaksis pola perutean, termasuk dukungan untuk karakter pengganti, grup token bernama, grup ekspresi reguler, dan pengubah grup. Instance URLPattern yang dibuat dengan sintaksis ini dapat melakukan tugas perutean umum, seperti mencocokkan dengan URL lengkap atau URL pathname, dan menampilkan informasi tentang kecocokan token dan grup.

Manfaat lain dari menyediakan pencocokan URL secara langsung di platform web adalah sintaksis umum dapat dibagikan dengan API lain yang juga harus cocok dengan URL.

Dukungan browser dan polyfill

URLPattern diaktifkan secara default di Chrome dan Edge versi 95 dan yang lebih baru.

Library urlpattern-polyfill menyediakan cara untuk menggunakan antarmuka URLPattern di browser atau lingkungan seperti Node yang tidak memiliki dukungan bawaan. Jika Anda menggunakan polyfill, pastikan Anda menggunakan deteksi fitur untuk memastikan bahwa Anda hanya memuatnya jika lingkungan saat ini tidak memiliki dukungan. Jika tidak, Anda akan kehilangan salah satu manfaat utama URLPattern: fakta bahwa lingkungan dukungan tidak perlu mendownload dan mengurai kode tambahan agar dapat menggunakannya.

if (!(globalThis && 'URLPattern' in globalThis)) {
  // URLPattern is not available, so the polyfill is needed.
}

Kompatibilitas sintaksis

Filosofi utama URLPattern adalah menghindari penemuan kembali. Jika sudah terbiasa dengan sintaksis perutean yang digunakan di Express atau Ruby on Rails, Anda tidak perlu mempelajari hal baru. Namun, mengingat sedikit perbedaan antara sintaksis dalam library perutean populer, sesuatu harus dipilih sebagai sintaksis dasar, dan desainer URLPattern memutuskan untuk menggunakan sintaksis pola dari path-to-regexp (meskipun bukan platform API-nya) sebagai titik awal.

Keputusan ini diambil setelah berkonsultasi dengan pengelola path-to-regexp saat ini.

Cara terbaik untuk memahami inti sintaksis yang didukung adalah dengan melihat dokumentasi untuk path-to-regexp. Anda dapat membaca dokumentasi yang ditujukan untuk publikasi di MDN di berandanya saat ini di GitHub.

Fitur tambahan

Sintaksis URLPattern adalah superset dari yang didukung path-to-regexp, karena URLPattern mendukung fitur yang tidak umum di antara library pemilihan rute: mencocokkan origin, termasuk karakter pengganti dalam nama host. Sebagian besar library pemilihan rute lainnya hanya menangani pathname, dan terkadang bagian penelusuran atau hash dari URL. Mereka tidak perlu memeriksa bagian origin URL, karena URL tersebut hanya digunakan untuk perutean origin yang sama dalam aplikasi web mandiri.

Mempertimbangkan origin akan membuka pintu untuk kasus penggunaan tambahan, seperti mengarahkan permintaan lintas origin di dalam pengendali peristiwa fetch pekerja layanan. Jika hanya merutekan URL origin yang sama, Anda dapat secara efektif mengabaikan fitur tambahan ini dan menggunakan URLPattern seperti library lainnya.

Contoh

Menyusun pola

Untuk membuat URLPattern, teruskan konstruktornya baik string atau objek yang propertinya berisi info tentang pola yang akan dicocokkan.

Meneruskan objek akan menawarkan kontrol yang paling eksplisit atas pola yang akan digunakan untuk mencocokkan setiap komponen URL. Pada yang paling panjang, ini bisa terlihat seperti

const p = new URLPattern({
  protocol: 'https',
  username: '',
  password: '',
  hostname: 'example.com',
  port: '',
  pathname: '/foo/:image.jpg',
  search: '*',
  hash: '*',
});

String kosong untuk properti hanya akan cocok jika bagian URL yang sesuai tidak ditetapkan. Karakter pengganti * akan cocok dengan nilai apa pun untuk bagian URL yang ditentukan.

Konstruktor menawarkan beberapa pintasan untuk penggunaan yang lebih sederhana. Menghapus search dan hash sepenuhnya, atau properti lainnya, setara dengan menetapkannya ke karakter pengganti '*'. Contoh di atas dapat disederhanakan untuk

const p = new URLPattern({
  protocol: 'https',
  username: '',
  password: '',
  hostname: 'example.com',
  port: '',
  pathname: '/foo/:image.jpg',
});

Sebagai pintasan tambahan, semua informasi tentang asal dapat diberikan dalam satu properti, baseURL, yang mengarah ke

const p = new URLPattern({
  pathname: '/foo/:image.jpg',
  baseURL: 'https://example.com',
});

Semua contoh ini mengasumsikan bahwa kasus penggunaan Anda melibatkan asal yang cocok. Jika Anda hanya ingin mencocokkan bagian lain dari URL, tidak termasuk asal (seperti yang berlaku untuk banyak skenario perutean origin tunggal "tradisional"), Anda dapat menghilangkan informasi origin sepenuhnya, dan hanya memberikan beberapa kombinasi properti pathname, search, dan hash. Seperti sebelumnya, properti yang dihapus akan diperlakukan seolah-olah ditetapkan ke pola karakter pengganti *.

const p = new URLPattern({pathname: '/foo/:image.jpg'});

Selain meneruskan objek ke konstruktor, Anda dapat menyediakan satu atau dua string. Jika satu string disediakan, string tersebut harus mewakili pola URL lengkap, termasuk informasi pola yang digunakan untuk mencocokkan origin. Jika Anda memberikan dua string, string kedua akan digunakan sebagai baseURL, dan string pertama dianggap relatif terhadap dasar tersebut.

Baik satu atau dua string disediakan, konstruktor URLPattern akan mengurai pola URL lengkap, membaginya menjadi komponen URL, dan memetakan setiap bagian pola yang lebih besar ke komponen yang sesuai. Ini berarti bahwa pada dasarnya, setiap URLPattern yang dibuat dengan string pada akhirnya direpresentasikan sama dengan URLPattern setara yang dibuat dengan objek. Konstruktor string hanyalah pintasan, bagi mereka yang lebih menyukai antarmuka yang tidak terlalu panjang.

const p = new URLPattern('https://example.com/foo/:image.jpg?*#*');

Saat menggunakan string untuk membuat URLPattern, ada beberapa peringatan yang perlu diingat.

Menghilangkan properti saat menggunakan objek untuk membuat URLPattern sama dengan memberikan karakter pengganti * untuk properti tersebut. Saat pola string URL lengkap diuraikan, jika salah satu komponen URL tidak memiliki nilai, pola akan diperlakukan seolah-olah properti komponen ditetapkan ke '', yang hanya akan cocok saat komponen tersebut kosong.

Saat menggunakan string, Anda harus menyertakan karakter pengganti secara eksplisit jika ingin digunakan dalam URLPattern yang dibuat.

// p1 and p2 are equivalent.
const p1 = new URLPattern('/foo', location.origin);
const p2 = new URLPattern({
  protocol: location.protocol,
  hostname: location.hostname,
  pathname: '/foo',
  search: '',
  hash: '',
});

// p3 and p4 are equivalent.
const p3 = new URLPattern('/foo?*#*', location.origin);
const p4 = new URLPattern({
  protocol: location.protocol,
  hostname: location.hostname,
  pathname: '/foo',
});

Anda juga harus menyadari bahwa menguraikan pola string ke dalam komponennya berpotensi ambigu. Terdapat karakter yang ditemukan di URL, seperti :, tetapi juga memiliki arti khusus dalam sintaksis pencocokan pola. Untuk menghindari ambiguitas ini, konstruktor URLPattern mengasumsikan bahwa salah satu karakter khusus tersebut adalah bagian dari pola, bukan bagian dari URL. Jika Anda ingin karakter ambigu ditafsirkan sebagai bagian dari URL, pastikan untuk meng-escape karakter tersebut dengan \` character. For example, the literal URLabout:blankshould be escaped as'about\:blank'` jika disediakan sebagai string.

Menggunakan pola

Setelah membuat URLPattern, Anda memiliki dua opsi untuk menggunakannya. Metode test() dan exec() mengambil input yang sama dan menggunakan algoritma yang sama untuk memeriksa kecocokan, dan hanya berbeda dalam nilai yang ditampilkan. test() menampilkan true jika ada kecocokan untuk input yang diberikan, dan false jika tidak. exec() menampilkan informasi mendetail tentang kecocokan bersama dengan grup tangkapan, atau null jika tidak ada kecocokan. Contoh berikut menunjukkan penggunaan exec(), tetapi Anda dapat menukar test() untuk salah satunya jika hanya menginginkan nilai yang ditampilkan boolean sederhana.

Salah satu cara untuk menggunakan metode test() dan exec() adalah dengan meneruskan string. Serupa dengan yang didukung oleh konstruktor, jika string tunggal diberikan, string tersebut harus berupa URL lengkap, termasuk origin. Jika dua string disediakan, string kedua akan diperlakukan sebagai nilai baseURL, dan string pertama dievaluasi sebagai relatif terhadap dasar tersebut.

const p = new URLPattern({
  pathname: '/foo/:image.jpg',
  baseURL: 'https://example.com',
});

const result = p.exec('https://example.com/foo/cat.jpg');
// result will contain info about the successful match.
// const result = p.exec('/foo/cat.jpg', 'https://example.com')
// is equivalent, using the baseURL syntax.

const noMatchResult = p.exec('https://example.com/bar');
// noMatchResult will be null.

Atau, Anda dapat meneruskan jenis objek yang sama dengan yang didukung konstruktor, dengan properti yang ditetapkan hanya ke bagian URL yang ingin Anda cocokkan.

const p = new URLPattern({pathname: '/foo/:image.jpg'});

const result = p.exec({pathname: '/foo/:image.jpg'});
// result will contain info about the successful match.

Jika menggunakan exec() pada URLPattern yang berisi karakter pengganti atau token, nilai yang ditampilkan akan memberi Anda informasi tentang nilai yang sesuai dalam URL input. Dengan demikian, Anda tidak perlu mengurai nilai tersebut sendiri.

const p = new URLPattern({
  hostname: ':subdomain.example.com',
  pathname: '/*/:image.jpg'
});

const result = p.exec('https://imagecdn1.example.com/foo/cat.jpg');
// result.hostname.groups.subdomain will be 'imagecdn1'
// result.pathname.groups[0] will be 'foo', corresponding to *
// result.pathname.groups.image will be 'cat'

Grup anonim dan bernama

Saat meneruskan string URL ke exec(), Anda akan mendapatkan kembali nilai yang memberi tahu bagian mana yang cocok dengan semua grup pola.

Nilai yang ditampilkan memiliki properti yang sesuai dengan komponen URLPattern, seperti pathname. Jadi, jika grup ditentukan sebagai bagian dari bagian pathname dari URLPattern, kecocokan dapat ditemukan dalam pathname.groups nilai yang ditampilkan. Kecocokan akan direpresentasikan secara berbeda, bergantung pada apakah pola yang sesuai adalah grup anonim atau bernama.

Anda dapat menggunakan indeks array untuk mengakses nilai pada pencocokan pola anonim. Jika ada beberapa pola anonim, indeks 0 akan mewakili nilai yang cocok untuk pola paling kiri, dengan 1 dan indeks lebih lanjut yang digunakan untuk pola berikutnya.

Saat menggunakan grup bernama dalam suatu pola, kecocokan tersebut akan ditampilkan sebagai properti yang namanya sesuai dengan setiap nama grup.

Dukungan dan normalisasi Unicode

URLPattern mendukung karakter Unicode dengan beberapa cara.

  • Grup bernama, seperti :café, dapat berisi karakter Unicode. Aturan yang digunakan untuk ID JavaScript yang valid berlaku untuk grup bernama.

  • Teks dalam pola akan otomatis dienkode menurut aturan yang sama dengan yang digunakan untuk encoding URL komponen tertentu tersebut. Karakter unicode dalam pathname akan dienkode persen, sehingga pola pathname seperti /café dinormalisasi ke /caf%C3%A9 secara otomatis. Karakter unicode dalam hostname otomatis dienkode menggunakan Punycode, bukan encoding persen.

  • Grup ekspresi reguler hanya boleh berisi karakter ASCII. Sintaksis ekspresi reguler mempersulit dan tidak aman untuk mengenkode karakter Unicode secara otomatis dalam grup ini. Jika ingin mencocokkan karakter Unicode dalam grup ekspresi reguler, Anda harus mengenkodenya secara manual, seperti (caf%C3%A9) agar cocok dengan café.

Selain mengenkode karakter Unicode, URLPattern juga melakukan normalisasi URL. Misalnya, /foo/./bar dalam komponen pathname diciutkan ke /foo/bar yang setara.

Jika ragu tentang cara pola input tertentu dinormalkan, periksa instance URLPattern yang dibuat menggunakan DevTools browser Anda.

Penutup

Demo Glitch yang disematkan di bawah mengilustrasikan kasus penggunaan inti URLPattern di dalam fetch event handler pekerja layanan, yang memetakan pola tertentu ke fungsi asinkron yang dapat menghasilkan respons terhadap permintaan jaringan. Konsep dalam contoh ini juga dapat diterapkan ke skenario perutean lainnya, baik sisi server maupun sisi klien.

Masukan dan rencana mendatang

Meskipun fungsi dasar untuk URLPattern telah tersedia di Chrome dan Edge, ada penambahan yang direncanakan. Beberapa aspek URLPattern masih dikembangkan, dan ada sejumlah pertanyaan terbuka tentang perilaku tertentu yang mungkin masih ditingkatkan. Sebaiknya Anda mencoba URLPattern dan berikan masukan apa pun melalui masalah GitHub.

Dukungan untuk template

Library path-to-regexp menyediakan compile() function yang secara efektif membalikkan perilaku pemilihan rute. compile() mengambil pola dan nilai untuk placeholder token, dan menampilkan string untuk jalur URL dengan nilai yang diganti.

Kami berharap dapat menambahkan ini ke URLPattern di masa mendatang, tetapi tidak berada dalam cakupan untuk rilis awal.

Mengaktifkan fitur platform web mendatang

Dengan asumsi URLPattern menjadi bagian platform web yang mapan, fitur lain yang dapat memperoleh manfaat dari pencocokan rute atau pola dapat ditambahkan sebagai primitif.

Terdapat diskusi berkelanjutan tentang penggunaan URLPattern untuk fitur yang diusulkan seperti pencocokan pola cakupan pekerja layanan, PWA sebagai pengendali file, dan pengambilan data spekulatif.

Ucapan terima kasih

Baca dokumen penjelasan asli untuk mengetahui daftar lengkap konfirmasi.