URLPattern udostępnia routing na platformę internetową

podejście do standaryzacji typowych przypadków użycia dopasowywania wzorów;

Tło

Przekierowywanie jest kluczowym elementem każdej aplikacji internetowej. W swojej istocie routing polega na pobraniu adresu URL, zastosowaniu do niego dopasowania wzorca lub innej logiki specyficznej dla aplikacji, a następnie wyświetleniu treści internetowych na podstawie uzyskanego wyniku. Przekierowywanie może być implementowane na kilka sposobów: czasami jest to kod działający na serwerze, który mapuje ścieżkę do plików na dysku, lub logika w aplikacji jednostronicowej, która czeka na zmiany bieżącej lokalizacji i tworzy odpowiedni element DOM do wyświetlenia.

Nie ma jednego, jednoznacznego standardu, ale programiści stron internetowych dążą do stosowania wspólnej składni do wyrażania wzorów kierowania adresów URL, które mają wiele wspólnego z regular expressions, ale zawierają też pewne dodatki specyficzne dla domeny, takie jak tokeny do dopasowywania segmentów ścieżki. Popularne frameworki po stronie serwera, takie jak Express i Ruby on Rails, używają tej składni (lub czegoś bardzo zbliżonego), a programiści JavaScript mogą używać modułów takich jak path-to-regexp lub regexpparam, aby dodać tę logikę do własnego kodu.

URLPattern to dodatek do platformy internetowej, który opiera się na fundamentach stworzonych przez te frameworki. Celem tego projektu jest ujednolicenie składni wzorca routingu, w tym obsługa symboli wieloznacznych, nazwanych grup symboli, grup wyrażeń regularnych i modyfikatorów grup. URLPattern instancje utworzone za pomocą tej składni mogą wykonywać typowe zadania związane z przekierowywaniem, takie jak dopasowywanie do pełnych adresów URL lub adresu URL pathname, a także zwracanie informacji o tokenach i pasujących grupach.

Kolejną zaletą udostępniania dopasowywania adresów URL bezpośrednio na platformie internetowej jest to, że wspólną składnię można udostępnić innym interfejsom API, które również muszą dopasowywać adresy URL.

Obsługa w przeglądarkach i polyfille

URLPattern jest domyślnie włączona w Chrome i Edge w wersji 95 i nowszych.

Biblioteka urlpattern-polyfill umożliwia korzystanie z interfejsu URLPattern w przeglądarkach lub środowiskach takich jak Node, które nie mają wbudowanego wsparcia. Jeśli używasz polyfill, upewnij się, że korzystasz z funkcji wykrywania, aby mieć pewność, że wczytujesz ją tylko wtedy, gdy bieżące środowisko nie obsługuje obecnego środowiska. W przeciwnym razie utracisz jedną z głównych zalet URLPattern: środowisko obsługi nie musi pobierać ani analizować dodatkowego kodu, aby go użyć.

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

Zgodność składni

Filozofia URLPattern opiera się na unikaniu wymyślania wszystkiego od nowa. Jeśli znasz już składnię routingu używaną w Express lub Ruby on Rails, nie musisz się uczyć niczego nowego. Ze względu na niewielkie różnice między składnią w popularnych bibliotekach kierowania należało wybrać składnię podstawową. Projektanci URLPattern zdecydowali się na użycie składu wzorca z path-to-regexp (choć nie jego interfejsu API) jako punktu wyjścia.

Podjęliśmy tę decyzję po konsultacjach z obecnym opiekunem pakietu path-to-regexp.

Najlepszym sposobem na zapoznanie się z podstawami obsługiwanej składni jest zapoznanie się z dokumentacją dotyczącą path-to-regexp. Możesz przeczytać dokumentację przeznaczoną do publikacji na MDN w jej obecnym miejscu na GitHub.

Dodatkowe funkcje

Składnia URLPattern jest superzetem tego, co obsługuje path-to-regexp, ponieważ URLPattern obsługuje funkcję rzadko spotykaną w bibliotekach routingu: dopasowywanie źródeł, w tym symboli wieloznacznych w nazwach hostów. Większość innych bibliotek routingu obsługuje tylko pathname, a czasem także część wyszukiwania lub hasz adresu URL. Nie muszą sprawdzać części źródła adresu URL, ponieważ są używane tylko do kierowania do tego samego źródła w ramach samodzielnej aplikacji internetowej.

Uwzględnianie źródeł otwiera drogę do dodatkowych zastosowań, takich jak przekierowywanie żądań między domenami w ramach elementu fetch service worker. Jeśli kierujesz tylko adresy URL z tego samego źródła, możesz zignorować tę dodatkową funkcję i używać URLPattern tak jak innych bibliotek.

Przykłady

Tworzenie wzoru

Aby utworzyć obiekt URLPattern, prześlij do jego konstruktora ciągi tekstowe lub obiekt, którego właściwości zawierają informacje o wzorze do dopasowania.

Przekazanie obiektu zapewnia największą kontrolę nad tym, jaki wzorzec ma być używany do dopasowywania poszczególnych elementów adresu URL. W najbardziej rozbudowanej formie może to wyglądać tak:

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

Podanie pustego ciągu znaków w przypadku usługi będzie się wiązać z dopasowaniem tylko wtedy, gdy odpowiednia część adresu URL nie jest ustawiona. Symbol wieloznaczny * będzie pasować do dowolnej wartości w danej części adresu URL.

Konstruktor udostępnia kilka skrótów ułatwiających korzystanie z funkcji. Całkowite pominięcie właściwości searchhash lub innych właściwości jest równoznaczne z ustawieniem dla nich znaku zapytania '*'. Powyższy przykład można uprościć do

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

Jako dodatkowy skrót wszystkie informacje o pochodzeniu można podać w jednej usłudze, baseURL, co prowadzi do

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

Wszystkie te przykłady zakładają, że Twój przypadek użycia obejmuje dopasowywanie źródeł. Jeśli interesuje Cię tylko dopasowanie innych części adresu URL, z wyłączeniem pochodzenia (jak w przypadku wielu „tradycyjnych” scenariuszy kierowania z pochodzeniem pojedynczym), możesz całkowicie pominąć informacje o pochodzeniu i podać tylko pewną kombinację właściwości pathname, searchhash. Podobnie jak wcześniej, pomijane właściwości będą traktowane tak, jakby były ustawione na wzór wieloznakowy *.

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

Zamiast przekazywać obiekt do konstruktora, możesz podać jeden lub dwa ciągi znaków. Jeśli podany jest jeden ciąg znaków, powinien on reprezentować pełny wzór adresu URL, w tym informacje o wzorze używane do dopasowywania pochodzenia. Jeśli podasz 2 ciągi, drugi z nich będzie używany jako baseURL, a pierwszy będzie traktowany w stosunku do tej podstawy.

Niezależnie od tego, czy podano 1 czy 2 ciągi znaków, konstruktor URLPattern przeanalizuje pełny wzór adresu URL, podzieli go na komponenty adresu URL i zmapuje każdą część większego wzorca na odpowiedni komponent. Oznacza to, że pod maską każda URLPattern utworzona za pomocą ciągu znaków jest reprezentowana tak samo jak odpowiednia URLPattern utworzona za pomocą obiektu. Konstruktor strings to tylko skrót dla tych, którzy wolą mniej rozbudowany interfejs.

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

Podczas tworzenia URLPattern za pomocą ciągów znaków należy pamiętać o kilku kwestiach.

Pominięcie właściwości podczas tworzenia obiektu URLPattern jest równoznaczne z użyciem w tej właściwości znaku zapytania *. Podczas analizowania pełnego wzorca ciągu znaków adresu URL, jeśli jeden z elementów adresu URL nie ma wartości, jest on traktowany tak, jakby jego właściwość była ustawiona na wartość '', która będzie pasować tylko wtedy, gdy element jest pusty.

Jeśli chcesz, aby w konstrukcji URLPattern były używane symbole wieloznaczne, musisz je uwzględnić w łańcuchach.

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

Pamiętaj też, że parsowanie wzoru ciągu na jego komponenty może być niejednoznaczne. Niektóre znaki, np. :, występują w adresach URL, ale mają też specjalne znaczenie w składni dopasowywania wzorca. Aby uniknąć tej niejednoznaczności, konstruktor URLPattern zakłada, że wszystkie te znaki specjalne są częścią wzorca, a nie adresu URL. Jeśli chcesz, aby niejednoznaczny znak był interpretowany jako część adresu URL, upewnij się, że jest on otoczony znakiem ucieczki (\` character. For example, the literal URLabout:blankshould be escaped as) w przypadku, gdy jest podawany jako ciąg znaków.

Korzystanie z wzoru

Po utworzeniu URLPattern masz 2 opcje jego użycia. Metody test()exec() przyjmują te same dane wejściowe i korzystają z tego samego algorytmu do sprawdzania dopasowania. Różnią się tylko zwracaną wartością. test()zwraca true, gdy występuje dopasowanie do podanych danych wejściowych, a w przeciwnym razie – false. exec() zwraca szczegółowe informacje o dopasowaniu wraz z grupami przechwytywania lub null, jeśli nie ma dopasowania. W poniższych przykładach użyto parametru exec(), ale jeśli chcesz zwrócić tylko prostą wartość logiczną, możesz użyć parametru test().

Jednym ze sposobów użycia metod test()exec() jest przekazanie ciągu znaków. Podobnie jak w przypadku konstruktora, jeśli podany jest pojedynczy ciąg znaków, powinien on być pełnym adresem URL, łącznie z pochodzeniem. Jeśli podano 2 ciągi tekstowe, drugi z nich jest traktowany jako wartość baseURL, a pierwszy jest oceniany w odniesieniu do tej wartości.

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.

Możesz też przekazać obiekt tego samego typu, który konstruktor obsługuje, z właściwościami ustawionymi tylko na te części adresu URL, które mają znaczenie.

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

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

Gdy używasz funkcji exec() w przypadku URLPattern, która zawiera symbole wieloznaczne lub tokeny, zwracana wartość zawiera informacje o odpowiednich wartościach w adresie URL wejściowym. Dzięki temu nie musisz samodzielnie wyodrębniać tych wartości.

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'

Anonimowe i nazywane grupy

Gdy przekazujesz ciąg znaków adresu URL do funkcji exec(), otrzymujesz wartość wskazującą, które fragmenty pasują do wszystkich grup w wzorze.

Zwracana wartość ma właściwości odpowiadające elementom obiektu URLPattern, np. pathname. Jeśli więc grupa została zdefiniowana jako część pathname w URLPattern, dopasowania można znaleźć w pathname.groups wartości zwracanej. Dopasowania są wyświetlane w różny sposób w zależności od tego, czy odpowiadający im wzór był grupą anonimową czy nazwaną.

Aby uzyskać dostęp do wartości w przypadku anonimowego dopasowania wzoru, możesz użyć indeksów tablicy. Jeśli jest więcej anonimowych wzorów, indeks 0 będzie reprezentować wartość pasującą do najbardziej lewego wzorca, a indeksy 1 i kolejne będą używane w przypadku kolejnych wzorów.

Gdy w wzorze używasz grup nazwanych, dopasowania będą widoczne jako właściwości, których nazwy odpowiadają nazwom poszczególnych grup.

Obsługa i normalizacja Unicode

URLPattern obsługuje znaki Unicode na kilka różnych sposobów.

  • Nazwane grupy, np. :café, mogą zawierać znaki Unicode. Reguły używane w przypadku prawidłowych identyfikatorów JavaScript mają zastosowanie do grup nazwanych.

  • Tekst we wzorze zostanie automatycznie zakodowany zgodnie z tymi samymi regułami, które są używane do kodowania adresów URL w danym komponencie. Znaki Unicode w wartościach pathname będą zakodowane za pomocą procentów, więc wzór pathname, np. /café, zostanie automatycznie znormalizowany do postaci /caf%C3%A9. Znaki Unicode w pliku hostname są automatycznie kodowane za pomocą kodu Punycode, a nie kodowania procentowego.

  • Grupy wyrażeń regularnych mogą zawierać tylko znaki ASCII. Składnia wyrażeń regularnych utrudnia i czyni niebezpiecznym automatyczne kodowanie znaków Unicode w tych grupach. Jeśli chcesz dopasować znak Unicode w grupie wyrażenia regularnego, musisz ręcznie zakodować go w procentach, np. (caf%C3%A9), aby dopasować café.

Oprócz kodowania znaków Unicode URLPattern normalizuje też adresy URL. Na przykład pole /foo/./bar w komponencie pathname jest zwinięte do odpowiadającego mu pola /foo/bar.

W razie wątpliwości co do sposobu normalizacji danego wzorca danych sprawdź utworzony obiekt URLPattern za pomocą DevTools w przeglądarce.

Podsumowanie

Zamieszczony poniżej pokaz na Glitch ilustruje podstawowy przypadek użycia URLPatternw ramach usługi fetch event handler, w której określone wzorce są mapowane na funkcje asynchroniczne, które mogą generować odpowiedzi na żądania sieciowe. Pojęcia opisane w tym przykładzie można zastosować również w innych scenariuszach przekierowywania, zarówno po stronie serwera, jak i po stronie klienta.

Opinie i plany na przyszłość

Podstawowe funkcje URLPattern są dostępne w Chrome i Edge, ale planujemy wprowadzić dodatkowe funkcje. Niektóre aspekty URLPattern nadal są rozwijane, a w przypadku niektórych zachowań nadal nie mamy odpowiedzi. Zachęcamy do wypróbowania URLPattern i przesłania opinii za pomocą problemu na GitHubie.

Obsługa szablonów

Biblioteka path-to-regexp udostępnia funkcję compile() function, która odwraca działanie routingu. Funkcja compile() przyjmuje wzór i wartości symboli zastępczych, a następnie zwraca ciąg znaków ścieżki adresu URL z podmienionymi wartościami.

Mamy nadzieję, że dodamy to do parametru URLPattern w przyszłości, ale nie udało się tego zrobić w ramach pierwszej wersji.

Włączanie przyszłych funkcji platformy internetowej

Zakładając, że URLPattern stanie się stałym elementem platformy internetowej, inne funkcje, które mogą korzystać z przekierowywania lub dopasowywania wzorca, mogą opierać się na nim jako na prymitywie.

Trwają dyskusje na temat używania URLPattern w przypadku proponowanych funkcji, takich jak dopasowywanie wzorca zakresu w usługach workerów, użytkowanie PWAs jako modułów obsługi plikówpobieranie wstępne w ramach spekulacji.

Podziękowania

Pełną listę podziękowań znajdziesz w pierwotnym dokumencie z informacjami.