Opublikowano: 22 lipca 2021 r.
Routing to kluczowy element każdej aplikacji internetowej. Routing polega na tym, że adres URL jest przetwarzany za pomocą dopasowywania wzorców lub innej logiki specyficznej dla aplikacji, a następnie na podstawie wyniku wyświetlane są treści internetowe. Przekierowywanie może być zaimplementowane na kilka sposobów:
- kod serwera, który mapuje ścieżki na pliki na dysku;
- Logika w aplikacji jednostronicowej, która czeka na zmiany bieżącej lokalizacji, a następnie tworzy i wyświetla odpowiedni fragment DOM.
Nie ma jednego standardu, ale programiści stron internetowych skłaniają się ku wspólnej składni wyrażania wzorców routingu adresów URL, która ma wiele wspólnego z regular expressions, ale zawiera pewne dodatki specyficzne dla domeny, takie jak tokeny do dopasowywania segmentów ścieżki.
Popularne platformy po stronie serwera, takie jak Express i Ruby on Rails, używają tej składni (lub bardzo podobnej), a programiści JavaScriptu mogą używać modułów takich jak path-to-regexp lub regexpparam, aby dodać tę logikę do własnego kodu.
URLPattern
jest dodatkiem do platformy internetowej, który opiera się na fundamencie stworzonym
przez te frameworki. Jego celem jest ujednolicenie składni wzorca routingu, w tym obsługa symboli wieloznacznych, nazwanych grup tokenów, grup wyrażeń regularnych i modyfikatorów grup. Instancje URLPattern utworzone za pomocą tej składni
mogą wykonywać typowe zadania związane z routingiem, takie jak dopasowywanie do pełnych adresów URL lub adresu URL
pathname
i zwracanie informacji o dopasowaniach tokenów i grup.
Kolejną zaletą udostępniania dopasowywania adresów URL bezpośrednio na platformie internetowej jest to, że wspólna składnia może być używana przez inne interfejsy API, które również muszą dopasowywać adresy URL.
Obsługa przeglądarek i wypełnienia
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ą wbudowanej obsługi. Jeśli używasz polyfillu, pamiętaj, aby używać wykrywania funkcji, aby mieć pewność, że ładujesz go tylko wtedy, gdy bieżące środowisko nie obsługuje danej funkcji. W przeciwnym razie utracisz jedną z kluczowych zalet URLPattern: środowiska pomocy nie będą musiały pobierać i parsować dodatkowego kodu, aby go używać.
if (!(globalThis && 'URLPattern' in globalThis)) {
// URLPattern is not available, so the polyfill is needed.
}
Zgodność składni
Podstawową zasadą URLPattern jest unikanie ponownego wynajdywania koła. Jeśli znasz już składnię routingu używaną w Express lub Ruby on Rails, nie musisz się uczyć niczego nowego. Jednak ze względu na niewielkie różnice między składniami w popularnych bibliotekach routingu trzeba było wybrać coś jako składnię podstawową. Projektanci URLPattern zdecydowali się użyć składni wzorca z path-to-regexp (choć nie jej interfejsu API) jako punktu wyjścia.
Ta decyzja została podjęta po dokładnych konsultacjach z obecnym opiekunem projektu 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 GitHubie.
Dodatkowe funkcje
Składnia URLPattern jest nadzbiorem składni obsługiwanej przez path-to-regexp, ponieważ URLPattern obsługuje rzadko spotykaną w bibliotekach routingu funkcję dopasowywania źródeł, w tym symboli wieloznacznych w nazwach hostów. Większość innych bibliotek routingu zajmuje się tylko pathname, a czasami częścią wyszukiwania lub haszowania adresu URL. Nigdy nie muszą sprawdzać części adresu URL dotyczącej pochodzenia, ponieważ są używane tylko do routingu w ramach tego samego pochodzenia w samodzielnej aplikacji internetowej.
Uwzględnianie źródeł otwiera drzwi do dodatkowych przypadków użycia, takich jak kierowanie żądań z różnych źródeł wewnątrz procesu roboczego usługi w fetch procedurze obsługi zdarzeń. Jeśli kierujesz tylko adresy URL z tego samego źródła, możesz zignorować tę dodatkową funkcję i używać URLPattern jak innych bibliotek.
Przykłady
Tworzenie wzoru
Aby utworzyć obiekt URLPattern, przekaż do jego konstruktora ciągi tekstowe lub obiekt, którego właściwości zawierają informacje o wzorcu do dopasowania.
Przekazywanie obiektu zapewnia najbardziej precyzyjną kontrolę nad tym, jakiego wzorca używać do dopasowywania poszczególnych komponentó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 właściwości spowoduje dopasowanie 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 oferuje kilka skrótów, które ułatwiają korzystanie z niego. Całkowite pominięcie właściwości search i hash lub innych właściwości jest równoznaczne z ustawieniem ich na symbol wieloznaczny '*'. Przykład można uprościć do:
const p = new URLPattern({
protocol: 'https',
username: '',
password: '',
hostname: 'example.com',
port: '',
pathname: '/foo/:image.jpg',
});
Dodatkowo wszystkie informacje o pochodzeniu mogą być podane w jednej właściwości, 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 do innych części adresu URL z wyłączeniem pochodzenia (jak w przypadku wielu scenariuszy routingu z jednego źródła), możesz całkowicie pominąć informacje o pochodzeniu i podać tylko kombinację właściwości pathname, search i hash. Tak jak wcześniej, pominięte właściwości będą traktowane tak, jakby były ustawione na wzorzec wieloznaczny *.
const p = new URLPattern({pathname: '/foo/:image.jpg'});
Zamiast przekazywać do konstruktora obiekt, możesz podać 1 lub 2 ciągi znaków. Jeśli podany jest jeden ciąg znaków, powinien on reprezentować pełny wzorzec adresu URL, w tym informacje o wzorcu używane do dopasowywania źródła. Jeśli podasz 2 ciągi znaków, drugi ciąg znaków będzie używany jako baseURL, a pierwszy ciąg znaków będzie traktowany jako względny względem tej bazy.
Niezależnie od tego, czy podasz jeden ciąg znaków, czy dwa, konstruktor URLPattern przeanalizuje pełny wzorzec adresu URL, rozbijając go na komponenty adresu URL i mapując każdą część większego wzorca na odpowiedni komponent. Oznacza to, że w praktyce każdy element URLPattern utworzony za pomocą ciągów znaków jest reprezentowany tak samo jak równoważny element URLPattern utworzony za pomocą obiektu. Konstruktor ciągów znaków to tylko skrót dla osób, które 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 używania obiektu do tworzenia URLPattern jest równoznaczne z podaniem symbolu wieloznacznego * dla tej właściwości. Gdy analizowany jest wzorzec pełnego ciągu adresu URL, a w jednym ze składników adresu URL brakuje wartości, jest on traktowany tak, jakby właściwość składnika była ustawiona na '', co będzie pasować tylko wtedy, gdy ten składnik jest pusty.
Jeśli używasz ciągów znaków, musisz wyraźnie uwzględnić symbole wieloznaczne, jeśli chcesz, aby były używane w konstruowanym URLPattern.
// 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 rozdzielenie wzorca ciągu znaków na jego komponenty może być niejednoznaczne. Istnieją znaki, np. :, które występują w adresach URL, ale mają też specjalne znaczenie w składni dopasowywania wzorców. Aby uniknąć tej niejednoznaczności, konstruktor URLPattern zakłada, że każdy z tych znaków specjalnych jest częścią wzorca, a nie adresu URL. Jeśli chcesz, aby niejednoznaczny znak był interpretowany jako część adresu URL, upewnij się, że jest on poprzedzony znakiem ucieczki \` character. For example, the literal URLabout:blankshould be escaped as'about\:blank'` w przypadku podania go jako ciągu znaków.
Używanie wzoru
Po utworzeniu URLPattern masz 2 możliwości jego użycia. Metody
test() i exec() przyjmują te same dane wejściowe i używają tego samego algorytmu do sprawdzania dopasowania. Różnią się tylko zwracaną wartością. test()
zwraca true, gdy dane wejściowe są zgodne, a w pozostałych przypadkach – false.
exec() zwraca szczegółowe informacje o dopasowaniu wraz z grupami przechwytywania lub null, jeśli nie ma dopasowania. W przykładach poniżej użyto funkcji exec(), ale w każdym z nich możesz użyć funkcji test(), jeśli chcesz uzyskać tylko wartość logiczną.
Jednym ze sposobów użycia metod test() i exec() jest przekazanie ciągów znaków.
Podobnie jak w przypadku konstruktora, jeśli podany jest pojedynczy ciąg znaków, powinien to być pełny adres URL, w tym pochodzenie. Jeśli podasz 2 ciągi tekstowe, drugi z nich będzie traktowany jako wartość baseURL, a pierwszy będzie oceniany względem tej podstawy.
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ć ten sam rodzaj obiektu, który obsługuje konstruktor, z właściwościami ustawionymi tylko na te części adresu URL, które chcesz dopasować.
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óre zawierają symbole wieloznaczne lub tokeny, zwracana wartość zawiera informacje o tym, jakie były odpowiednie wartości w adresie URL wejściowym. Dzięki temu nie musisz samodzielnie analizować 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'
Grupy anonimowe i nazwane
Gdy przekażesz ciąg znaków adresu URL do funkcji exec(), otrzymasz wartość informującą, które części pasują do wszystkich grup wzorca.
Wartość zwracana ma właściwości odpowiadające komponentom elementu URLPattern, np. pathname. Jeśli grupa została zdefiniowana w części pathname elementu URLPattern, dopasowania można znaleźć w pathname.groups wartości zwracanej. Dopasowania są reprezentowane w różny sposób w zależności od tego, czy odpowiedni wzorzec był grupą anonimową czy nazwaną.
Możesz używać indeksów tablicy, aby uzyskać dostęp do wartości w przypadku anonimowego dopasowania wzorca.
Jeśli istnieje kilka anonimowych wzorców, indeks 0 reprezentuje pasującą wartość dla wzorca znajdującego się najbardziej po lewej stronie, a indeksy 1 i dalsze są używane w przypadku kolejnych wzorców.
Gdy w wzorcu używasz nazwanych grup, dopasowania są 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. W przypadku nazwanych grup obowiązują reguły dotyczące prawidłowych identyfikatorów JavaScript.Tekst w wzorcu zostanie automatycznie zakodowany zgodnie z tymi samymi regułami, które są używane do kodowania adresu URL danego komponentu. Znaki Unicode w
pathnamezostaną zakodowane za pomocą procentów, więc wzorzecpathname, np./café, zostanie automatycznie znormalizowany do/caf%C3%A9. Znaki Unicode whostnamesą automatycznie kodowane za pomocą Punycode, a nie kodowania procentowego.Grupy wyrażeń regularnych muszą 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żeń regularnych, musisz ręcznie zakodować go w procentach, np.
(caf%C3%A9), aby dopasowaćcafé.
Oprócz kodowania znaków Unicode funkcja URLPattern przeprowadza też normalizację adresu URL. Na przykład element /foo/./bar w komponencie pathname jest zwijany do równoważnego elementu /foo/bar.
Jeśli masz wątpliwości, jak dany wzorzec wejściowy został znormalizowany, sprawdź utworzoną instancję URLPattern za pomocą DevTools w przeglądarce.
Połącz wszystkie elementy
Wersja demonstracyjna Glitch ilustruje podstawowy przypadek użycia URLPatternw ramach procesu roboczego usługiURLPatternfetch event handler, mapując określone wzorce na funkcje asynchroniczne, które mogą generować odpowiedź na żądania sieciowe. Koncepcje przedstawione w tym przykładzie można zastosować również w przypadku innych scenariuszy routingu, zarówno po stronie serwera, jak i po stronie klienta.
Opinie i plany na przyszłość
Podstawowe funkcje URLPattern są już dostępne w Chrome i Edge, ale planujemy dodać kolejne. Niektóre aspekty URLPattern są wciąż w trakcie opracowywania, a w przypadku niektórych zachowań pozostaje wiele otwartych pytań, które mogą jeszcze zostać dopracowane. Zachęcamy do wypróbowania tej funkcjiURLPattern i przesłania opinii w GitHub.
Obsługa szablonów
Biblioteka path-to-regexp udostępnia compile() function, który skutecznie odwraca działanie routingu. compile() przyjmuje wzorzec i wartości symboli zastępczych tokenów oraz zwraca ciąg tekstowy ścieżki URL z podstawionymi wartościami.
Mamy nadzieję, że w przyszłości dodamy tę funkcję do URLPattern, ale nie jest ona objęta zakresem początkowej 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 wzorców, mogą na nim bazować jako na elemencie podstawowym.
Trwają dyskusje na temat używania URLPattern w przypadku proponowanych funkcji, takich jak dopasowywanie wzorców zakresu service workerów, aplikacje PWA jako programy obsługujące pliki i spekulacyjne pobieranie wstępne.
Pełną listę podziękowań znajdziesz w oryginalnym dokumencie z wyjaśnieniami.