URLPattern, web platformuna yönlendirme sağlar

Yaygın kalıp eşleştirme kullanım alanlarını standartlaştırmaya yönelik bir yaklaşım.

Arka plan

Yönlendirme, her web uygulamasının önemli bir parçasıdır. Yönlendirmenin temelinde, bir URL'yi almak, URL'ye bazı kalıp eşleştirmeleri veya uygulamaya özgü başka bir mantık uygulamak ve ardından genellikle sonuca göre web içeriği görüntülemek yer alır. Yönlendirme, çeşitli şekillerde uygulanabilir: Bazen bir sunucuda çalışan ve diskteki dosyaların yolunu eşleyen bir koddur veya tek sayfalık bir uygulamada mevcut konumda değişiklik olmasını bekleyen ve görüntülemek için ilgili bir DOM parçası oluşturan mantıktır.

Kesin bir standart olmasa da web geliştiricileri, URL yönlendirme kalıplarını ifade etmek için regular expressions ile çok ortak noktası olan ancak yol segmentlerini eşleştirmek için jetonlar gibi alana özgü bazı eklemeler içeren ortak bir söz dizimi kullanmaya yönelmiştir. Express ve Ruby on Rails gibi popüler sunucu tarafı çerçeveler bu söz dizimini (veya buna çok yakın bir yapıyı) kullanır. JavaScript geliştiricileri de bu mantığı kendi kodlarına eklemek için path-to-regexp veya regexpparam gibi modülleri kullanabilir.

URLPattern, bu çerçevelerin oluşturduğu temeli temel alan web platformuna eklenen bir özelliktir. Amaç, joker karakterler, adlandırılmış jeton grupları, normal ifade grupları ve grup değiştiriciler için destek de dahil olmak üzere yönlendirme kalıbı söz dizimini standartlaştırmaktır. Bu söz dizimi ile oluşturulan URLPattern örnekleri, tam URL'lerle veya bir URLpathname ile eşleştirme gibi ortak yönlendirme görevlerini gerçekleştirebilir ve jeton ile grup eşleşmeleri hakkında bilgi döndürebilir.

URL eşleştirmeyi doğrudan web platformunda sağlamanın bir diğer avantajı da, URL'lerle eşleşmesi gereken diğer API'lerle ortak bir söz dizimi paylaşılabilmesidir.

Tarayıcı desteği ve polyfill'ler

URLPattern, Chrome ve Edge 95 ve sonraki sürümlerinde varsayılan olarak etkindir.

urlpattern-polyfill kitaplığı, URLPattern arayüzünü tarayıcılarda veya yerleşik destekten yoksun Node gibi ortamlarda kullanmanın bir yolunu sağlar. Polifill kullanıyorsanız yalnızca mevcut ortamda destek yoksa yüklediğinizden emin olmak için özellik algılama özelliğini kullandığınızdan emin olun. Aksi takdirde, URLPattern'ün en önemli avantajlarından birini kaybedersiniz: Destek ortamlarının, kullanmak için ek kod indirip ayrıştırması gerekmez.

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

Söz dizimi uyumluluğu

URLPattern'ün temel felsefesi, yeniden keşif yapmaktan kaçınmaktır. Express veya Ruby on Rails'de kullanılan yönlendirme söz dizimine aşinaysanız yeni bir şey öğrenmeniz gerekmez. Ancak popüler yönlendirme kitaplıklarındaki söz dizimi farklılıkları göz önüne alındığında, temel söz dizimi olarak bir şey seçilmesi gerekiyordu. URLPattern'ün tasarımcıları, başlangıç noktası olarak path-to-regexp'teki kalıp söz dizimini (API yüzeyi değil) kullanmaya karar verdi.

Bu karar, path-to-regexp'ün mevcut geliştiricisiyle yapılan ayrıntılı bir danışma sürecinin ardından alınmıştır.

Desteklenen söz dizimi çekirdeğini öğrenmenin en iyi yolu, path-to-regexp ile ilgili dokümanları incelemektir. MDN'de yayınlanmak üzere hazırlanan dokümanları GitHub'daki mevcut ana sayfasında okuyabilirsiniz.

Ek özellikler

URLPattern, yönlendirme kitaplıkları arasında yaygın olmayan bir özelliği desteklediği için URLPattern'ün söz dizimi, path-to-regexp'ün desteklediklerinin bir üst kümesidir: ana makine adlarına joker karakterler ekleyerek kökenleri eşleştirme. Diğer yönlendirme kitaplıklarının çoğu yalnızca pathname ve bazen de URL'nin arama veya karma kısmıyla ilgilenir. Yalnızca kendi kendine yeten bir web uygulamasında aynı kaynak yönlendirmesi için kullanıldığından, URL'nin kaynak bölümünü kontrol etmeleri gerekmez.

Kaynakları hesaba katmak, kaynak ötesi isteklerini bir hizmet çalışanının fetch etkinlik işleyicisinde yönlendirme gibi ek kullanım alanlarına kapı açar. Yalnızca aynı kaynaktan gelen URL'leri yönlendiriyorsanız bu ek özelliği etkili bir şekilde yoksayabilir ve URLPattern'yi diğer kitaplıklar gibi kullanabilirsiniz.

Örnekler

Deseni oluşturma

URLPattern oluşturmak için dize veya eşlenecek desenle ilgili bilgiler içeren özellikleri olan bir nesne gönderin.

Bir nesne iletmek, her URL bileşenini eşleştirmek için hangi kalıbın kullanılacağı konusunda en net kontrolü sağlar. En ayrıntılı şekilde şu şekilde görünebilir:

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

Bir mülk için boş bir dize sağlandığında eşleşme yalnızca URL'nin ilgili bölümü ayarlanmamışsa gerçekleşir. Joker karakter *, URL'nin belirli bir bölümü için herhangi bir değerle eşleşir.

Oluşturucu, daha kolay kullanım için çeşitli kısayollar sunar. search ve hash veya diğer özelliklerin tamamen atlanması, bunları '*' joker karakterine ayarlamaya eşdeğerdir. Yukarıdaki örnek şu şekilde basitleştirilebilir:

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

Ek bir kısayol olarak, kaynakla ilgili tüm bilgiler tek bir mülkte (baseURL) sağlanabilir. Bu,

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

Bu örneklerin tümü, kullanım alanınızda eşleşen kaynakların bulunduğu varsayılır. Yalnızca kaynağı hariç URL'nin diğer bölümlerinde eşleşme yapmak istiyorsanız (birçok "geleneksel" tek kaynaklı yönlendirme senaryosundaki gibi) kaynak bilgilerini tamamen atlayabilir ve yalnızca pathname, search ve hash özelliklerinin bir kombinasyonunu sağlayabilirsiniz. Atlanan özellikler, daha önce olduğu gibi * joker karakter kalıbına ayarlanmış gibi ele alınır.

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

Oluşturucuya bir nesne göndermek yerine bir veya iki dize sağlayabilirsiniz. Tek bir dize sağlanırsa bu dize, kaynağı eşleştirmek için kullanılan kalıp bilgileri de dahil olmak üzere tam bir URL kalıbını temsil etmelidir. İki dize sağlarsanız ikinci dize baseURL olarak kullanılır ve ilk dize bu tabana göre kabul edilir.

Bir veya iki dize sağlanırsa URLPattern kurucusu, URL kalıbının tamamını ayrıştırarak URL bileşenlerine ayırır ve daha büyük kalıbın her bölümünü ilgili bileşenle eşleştirir. Bu, arka planda, dizelerle oluşturulan her URLPattern nesnesinin, nesneyle oluşturulan eşdeğer bir URLPattern ile aynı şekilde temsil edildiği anlamına gelir. strings yapıcısı, daha az ayrıntılı bir arayüz tercih edenler için yalnızca bir kısayoldur.

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

URLPattern oluşturmak için dize kullanırken dikkate almanız gereken birkaç nokta vardır.

URLPattern oluşturmak için bir nesne kullanırken bir mülkü dışarıda bırakmak, söz konusu mülk için bir * joker karakteri sağlamaya eşdeğerdir. Tam URL dize kalıbı ayrıştırılırken URL bileşenlerinden birinde değer eksikse bileşenin özelliği '' olarak ayarlanmış gibi değerlendirilir. Bu durumda yalnızca bileşen boş olduğunda eşleşme olur.

Dize kullanırken, oluşturulan URLPattern içinde kullanılmasını istediğiniz joker karakterleri açıkça eklemeniz gerekir.

// 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',
});

Bir dize kalıbını bileşenlerine ayırmanın belirsiz olabileceğini de unutmayın. : gibi, URL'lerde bulunan ancak kalıp eşleştirme söz diziminde özel anlamı olan karakterler vardır. Bu belirsizliği önlemek için URLPattern kurucusu, bu özel karakterlerin URL'nin değil, bir kalıbın parçası olduğunu varsayar. Anlamsız bir karakterin URL'nin bir parçası olarak yorumlanmasını istiyorsanız karakteri, dize olarak sağlandığında \` character. For example, the literal URLabout:blankshould be escaped as'about\:blank' ile kaçak karakter olarak eklediğinizden emin olun.

Deseni kullanma

Bir URLPattern oluşturduktan sonra bunu kullanmanın iki seçeneğiniz vardır. test() ve exec() yöntemleri aynı girişi alır ve eşleşme olup olmadığını kontrol etmek için aynı algoritmayı kullanır. Bu yöntemler arasındaki tek fark, döndürülen değerdir. test(), belirtilen girişle eşleşme olduğunda true, aksi takdirde false değerini döndürür. exec(), yakalama gruplarıyla birlikte eşleşmeyle ilgili ayrıntılı bilgi döndürür veya eşleşme yoksa null döndürür. Aşağıdaki örneklerde exec() kullanılmaktadır ancak yalnızca basit bir boole döndürülen değer istiyorsanız bunların herhangi biri için test() kullanabilirsiniz.

test() ve exec() yöntemlerini kullanmanın bir yolu, dize göndermektir. Oluşturucunun desteklediğine benzer şekilde, tek bir dize sağlanırsa bu dize, kaynak da dahil olmak üzere tam bir URL olmalıdır. İki dize sağlanırsa ikinci dize baseURL değeri olarak değerlendirilir ve ilk dize bu tabana göre değerlendirilir.

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.

Alternatif olarak, URL'nin eşleşmesi gereken yalnızca bölümlerine ayarlanmış özelliklere sahip, oluşturucunun desteklediği türde bir nesne de iletebilirsiniz.

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

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

exec() işlevi, joker karakter veya jeton içeren bir URLPattern üzerinde kullanıldığında döndürülen değer, giriş URL'sindeki ilgili değerlerin ne olduğu hakkında bilgi verir. Bu sayede, bu değerleri kendiniz ayrıştırmak zorunda kalmazsınız.

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'

Anonim ve adlandırılmış gruplar

exec() işlevine bir URL dizesi ilettiğinizde, hangi bölümlerin kalıbın tüm gruplarıyla eşleştiğini belirten bir değer alırsınız.

Döndürülen değer, URLPattern bileşenlerine (ör. pathname) karşılık gelen özelliklere sahiptir. Dolayısıyla, bir grup URLPattern değerinin pathname kısmı olarak tanımlandıysa eşleşmeler, döndürülen değerin pathname.groups kısmında bulunabilir. Eşleşmeler, ilgili kalıbın anonim veya adlandırılmış bir grup olup olmadığına bağlı olarak farklı şekilde temsil edilir.

Anonim kalıp eşleşmesinin değerlerine erişmek için dizi dizinlerini kullanabilirsiniz. Birden fazla anonim kalıp varsa 0 dizini, en soldaki kalıp için eşleşen değeri temsil eder. 1 ve sonraki dizinler ise sonraki kalıplar için kullanılır.

Bir kalıpta adlandırılmış gruplar kullanıldığında eşleşmeler, adları her grup adına karşılık gelen özellikler olarak gösterilir.

Unicode desteği ve normalleştirme

URLPattern, Unicode karakterlerini birkaç farklı şekilde destekler.

  • :café gibi adlandırılmış gruplar Unicode karakterleri içerebilir. Geçerli JavaScript tanımlayıcıları için kullanılan kurallar, adlandırılmış gruplar için geçerlidir.

  • Bir kalıptaki metin, ilgili bileşenin URL kodlaması için kullanılan kurallara göre otomatik olarak kodlanır. pathname içindeki Unicode karakterleri yüzde olarak kodlanır. Bu nedenle, /café gibi bir pathname kalıbı otomatik olarak /caf%C3%A9 olarak normalleştirilir. hostname içindeki Unicode karakterleri, yüzde kodlama yerine Punycode kullanılarak otomatik olarak kodlanır.

  • Normal ifade grupları yalnızca ASCII karakterleri içermelidir. Normal ifade söz dizimi, bu gruplardaki Unicode karakterlerinin otomatik olarak kodlanmasını zor ve güvenli olmayan bir hale getirir. Normal ifade grubunda bir Unicode karakteriyle eşleşmek istiyorsanız karakteri manuel olarak yüzde kodlamanız gerekir (ör. café ile eşleşmek için (caf%C3%A9)).

URLPattern, Unicode karakterlerini kodlamaya ek olarak URL normalleştirmesi de gerçekleştirir. Örneğin, pathname bileşenindeki /foo/./bar, eşdeğer /foo/bar değerine daraltılır.

Belirli bir giriş kalıbının nasıl normalleştirildiğinden şüphe duyuyorsanız tarayıcınızın DevTools aracını kullanarak oluşturulan URLPattern örneğini inceleyin.

Tüm unsurların birleşimi

Aşağıda yerleştirilmiş Glitch demosunda, belirli kalıpları ağ isteklerine yanıt oluşturabilecek asenkron işlevlerle eşleyen URLPattern bir hizmet çalışanının fetch event handler içindeki temel kullanım alanı gösterilmektedir. Bu örnekteki kavramlar, sunucu tarafı veya istemci tarafı diğer yönlendirme senaryolarına da uygulanabilir.

Geri bildirim ve gelecek planları

URLPattern'ün temel işlevleri Chrome ve Edge'e eklendi ancak daha fazla ekleme planlanıyor. URLPattern'ün bazı özellikleri henüz geliştirilme aşamasındadır ve belirli davranışlarla ilgili olarak daha da hassaslaştırılabilecek birçok açık soru vardır. URLPattern'yi denemenizi ve GitHub sorunu üzerinden geri bildirimde bulunmanızı öneririz.

Şablon oluşturma desteği

path-to-regexp kitaplığı, yönlendirme davranışını etkili bir şekilde tersine çeviren bir compile() function sağlar. compile(), jeton yer tutucuları için bir kalıp ve değerler alır ve bu değerlerin yerine geçtiği bir URL yolu dizesi döndürür.

Gelecekte bu özelliği URLPattern'a eklemeyi umuyoruz ancak bu özellik ilk sürümün kapsamına dahil değildir.

Gelecekteki web platformu özelliklerini etkinleştirme

URLPattern'ün web platformunun yerleşik bir parçası haline geleceği varsayıldığında, yönlendirme veya kalıp eşleştirmeden yararlanabilecek diğer özellikler, bu özelliğin üzerine temel öğe olarak inşa edilebilir.

Hizmet çalışanı kapsamı desen eşleştirme, dosya işleyici olarak PWA'lar ve tahmini ön getirme gibi önerilen özellikler için URLPattern kullanımıyla ilgili devam eden tartışmalar var.

Teşekkür ederiz

Teşekkürlerin tam listesi için orijinal açıklama belgesine bakın.