URLPattern menghadirkan pemilihan rute ke platform web

Dipublikasikan: 22 Juli 2021

Perutean adalah bagian penting dari setiap aplikasi web. Pada dasarnya, perutean mengambil URL, menerapkan pencocokan pola atau logika khusus aplikasi lainnya ke URL tersebut, lalu, biasanya, menampilkan konten web berdasarkan hasilnya. Perutean dapat diterapkan dengan beberapa cara:

  • Kode server yang memetakan jalur ke file di disk
  • Logika di aplikasi halaman tunggal yang menunggu perubahan pada lokasi saat ini, lalu membuat dan menampilkan bagian DOM yang sesuai.

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

URLPattern adalah tambahan pada platform web yang dibangun berdasarkan fondasi yang dibuat oleh framework ini. Tujuannya adalah untuk menstandardisasi 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 perlu mencocokkan 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 untuk menggunakannya.

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

Kompatibilitas sintaksis

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

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

Cara terbaik untuk memahami inti sintaksis yang didukung adalah dengan membaca dokumentasi untuk path-to-regexp. Anda dapat membaca dokumentasi yang ditujukan untuk publikasi di MDN di lokasi 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 perutean: pencocokan origin, termasuk karakter pengganti di nama host. Sebagian besar library perutean lainnya hanya menangani pathname, dan terkadang search atau hash dari URL. Pengguna tidak perlu memeriksa bagian asal URL, karena hanya digunakan untuk perutean origin yang sama dalam aplikasi web mandiri.

Memperhitungkan asal membuka peluang untuk kasus penggunaan tambahan, seperti merutekan permintaan lintas asal di dalam pengendali peristiwa fetch service worker. Jika hanya merutekan URL origin yang sama, Anda dapat mengabaikan fitur tambahan ini dan menggunakan URLPattern seperti library lainnya.

Contoh

Membangun pola

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

Meneruskan objek menawarkan kontrol paling eksplisit atas pola yang akan digunakan untuk mencocokkan setiap komponen URL. Dalam bentuk yang paling lengkap, ini dapat terlihat seperti

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

Menyediakan 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 tertentu.

Konstruktor menawarkan beberapa pintasan untuk penggunaan yang lebih sederhana. Menghapus search dan hash sepenuhnya, atau properti lainnya, sama dengan menyetelnya ke karakter pengganti '*'. Contohnya dapat disederhanakan menjadi:

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 pencocokan asal. Jika Anda hanya tertarik untuk mencocokkan bagian lain dari URL, tidak termasuk asal (seperti yang terjadi pada banyak skenario perutean asal tunggal), Anda dapat menghilangkan informasi asal sepenuhnya, dan hanya memberikan beberapa kombinasi properti pathname, search, dan hash. Seperti sebelumnya, properti yang tidak disertakan akan diperlakukan seolah-olah ditetapkan ke pola wildcard *.

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

Sebagai alternatif untuk meneruskan objek ke konstruktor, Anda dapat memberikan satu atau dua string. Jika satu string diberikan, string tersebut harus merepresentasikan pola URL lengkap, termasuk informasi pola yang digunakan untuk mencocokkan asal. Jika Anda memberikan dua string, string kedua akan digunakan sebagai baseURL, dan string pertama dianggap relatif terhadap basis tersebut.

Baik satu atau dua string yang diberikan, konstruktor URLPattern akan mem-parsing pola URL lengkap, memecahnya menjadi komponen URL, dan memetakan setiap bagian dari pola yang lebih besar ke komponen yang sesuai. Artinya, di balik layar, setiap URLPattern yang dibuat dengan string akan direpresentasikan sama seperti URLPattern yang setara yang dibuat dengan objek. Konstruktor string hanyalah pintasan, bagi mereka yang lebih menyukai antarmuka yang lebih sederhana.

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

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

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

Saat menggunakan string, Anda harus menyertakan karakter pengganti secara eksplisit jika ingin karakter tersebut 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 mengurai pola string ke dalam komponennya berpotensi ambigu. Ada karakter, seperti :, yang ditemukan di URL, tetapi juga memiliki arti khusus dalam sintaksis pencocokan pola. Untuk menghindari ambiguitas ini, konstruktor URLPattern mengasumsikan bahwa karakter khusus tersebut adalah bagian dari pola, bukan bagian dari URL. Jika Anda ingin karakter ambigu ditafsirkan sebagai bagian dari URL, pastikan untuk melakukan escape dengan \` character. For example, the literal URLabout:blankshould be escaped as'about\:blank'` saat diberikan sebagai string.

Menggunakan pola

Setelah membuat URLPattern, Anda memiliki dua opsi untuk menggunakannya. Metode test() dan exec() menggunakan input yang sama dan 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 beserta 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.

Salah satu cara untuk menggunakan metode test() dan exec() adalah dengan meneruskan string. Mirip dengan yang didukung konstruktor, jika satu string diberikan, string tersebut harus berupa URL lengkap, termasuk origin. Jika dua string diberikan, string kedua diperlakukan sebagai nilai baseURL, dan string pertama dievaluasi relatif terhadap basis 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 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.

Saat menggunakan exec() pada URLPattern yang berisi karakter pengganti atau token, nilai yang ditampilkan akan memberi Anda informasi tentang nilai yang sesuai dalam URL input. Hal ini dapat menghemat waktu Anda karena 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 Anda 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 pathname URLPattern, kecocokan dapat ditemukan di pathname.groups nilai yang ditampilkan. Kecocokan ditampilkan secara berbeda bergantung pada apakah pola yang sesuai adalah grup anonim atau bernama.

Anda dapat menggunakan indeks array untuk mengakses nilai kecocokan pola anonim. Jika ada beberapa pola anonim, indeks 0 merepresentasikan nilai yang cocok untuk pola paling kiri, dengan 1 dan indeks selanjutnya digunakan untuk pola berikutnya.

Saat menggunakan grup bernama dalam pola, kecocokan 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 pengidentifikasi JavaScript yang valid berlaku untuk grup bernama.

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

  • Grup ekspresi reguler hanya boleh berisi karakter ASCII. Sintaksis ekspresi reguler membuat encoding karakter Unicode dalam grup ini menjadi sulit dan tidak aman. Jika Anda ingin mencocokkan karakter Unicode dalam grup ekspresi reguler, Anda harus mengenkodenya secara manual dengan persentase, seperti (caf%C3%A9) untuk mencocokkan café.

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

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

Menyatukan semuanya

Demo Glitch mengilustrasikan kasus penggunaan inti URLPattern di dalam fetch event handler service worker, memetakan pola tertentu ke fungsi asinkron yang dapat menghasilkan respons terhadap permintaan jaringan. Konsep dalam contoh ini juga dapat diterapkan pada skenario perutean lainnya, baik di 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 dalam pengembangan, dan ada sejumlah pertanyaan terbuka tentang perilaku tertentu yang mungkin masih perlu disempurnakan. Sebaiknya Anda mencoba URLPattern dan memberikan masukan melalui masalah GitHub.

Dukungan untuk pembuatan template

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

Kami berharap dapat menambahkannya ke URLPattern pada masa mendatang, tetapi hal ini tidak termasuk dalam cakupan rilis awal.

Mengaktifkan fitur platform web mendatang

Dengan asumsi URLPattern menjadi bagian yang sudah mapan dari platform web, fitur lain yang dapat memanfaatkan perutean atau pencocokan pola dapat dibangun di atasnya sebagai primitif.

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

Lihat dokumen penjelasan asli untuk mengetahui daftar lengkap ucapan terima kasih.