podejście do standaryzacji typowych przypadków użycia dopasowywania wzorów;
Tło
Przekierowywanie jest kluczowym elementem każdej aplikacji internetowej. Zasadniczo routing obejmuje pobieranie adresu URL, stosowanie do niego dopasowania do wzorca lub innej logiki specyficznej dla aplikacji, a potem zazwyczaj wyświetlanie treści z internetu na podstawie uzyskanych wyników. 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.
Chociaż nie ma jednego jednoznacznego standardu, programiści stron internetowych otrzymywali wspólną składnię do wyrażania wzorców routingu adresów URL, które mają wiele wspólnego z regular expressions
, ale oferują pewne dodatki specyficzne dla domeny, takie jak tokeny dopasowujące segmenty ścieżek.
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. Jego celem jest ustandaryzowanie składni wzorca routingu, w tym obsługę 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 przekierowywaniem, takie jak dopasowywanie do pełnych adresów URL lub adresu URL pathname
, a także zwracać informacje 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, pamiętaj, aby zastosować wykrywanie funkcji, 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
: środowiska obsługi nie muszą pobierać ani analizować dodatkowego kodu, aby go używać.
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 elementu URLPattern
jest nadzbiorem funkcji obsługiwanych przez path-to-regexp
, ponieważ URLPattern
obsługuje nietypową funkcję wśród bibliotek routingu: dopasowywanie elementów origins, w tym symboli wieloznacznych w nazwach hostów. Większość innych bibliotek routingu obsługuje po prostu pathname, a czasami fragment adresu URL zawierający wyszukiwane lub zaszyfrowane fragmenty. 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 wzór 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 dostosowaniem 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 search
i hash
lub innych właściwości jest równoznaczne z ustawieniem dla nich znaku zapytania '*'
. Powyższy przykład można uprościć,
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 routingu z pochodzeniem pojedynczym), możesz całkowicie pominąć informacje o pochodzeniu i podać tylko pewną kombinację właściwości pathname
, search
i hash
. 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 będzie używany jako baseURL
, a pierwszy będzie traktowany względem 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 elementu URLPattern
ciągów tekstowych musisz pamiętać o kilku kwestiach.
W przypadku używania obiektu do konstruowania obiektu URLPattern
pozostawienie właściwości wyłączonej jest równoważne z dodaniem dla tej właściwości symbolu wieloznacznego *
. 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 URL
about:blankshould be escaped as
) w przypadku, gdy jest podawany jako ciąg znaków.
Korzystanie z wzoru
Po utworzeniu obiektu URLPattern
możesz go użyć na 2 sposoby. Metody test()
i 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 wartość true
, jeśli dane wejściowe pasują do podanych wartości. W przeciwnym razie zwraca false
.
exec()
zwraca szczegółowe informacje o dopasowaniu wraz z grupami przechwytywania lub null
w przypadku braku 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()
.
Jedną z metod użycia metod test()
i 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żna też przekazać obiekt tego samego rodzaju, który obsługuje konstruktor, z właściwościami ustawionymi tylko na te części adresu URL, które są dla Ciebie istotne.
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 znaki zapytania 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 wzorzec był anonimową czy nazwaną grupą.
Aby uzyskać dostęp do wartości w przypadku anonimowego dopasowania wzoru, możesz użyć indeksów tablicy.
Jeśli istnieje wiele wzorców anonimowych, indeks 0
będzie reprezentował wartość dopasowania dla wzorca znajdującego się skrajnie po lewej stronie, przy czym w kolejnych wzorcach używane jest 1
i kolejne indeksy.
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 wzorcu będzie automatycznie kodowany zgodnie z tymi samymi regułami, które są używane przy kodowaniu adresów URL tego konkretnego komponentu. Znaki Unicode w wartościach
pathname
będą zakodowane za pomocą procentów, więc wzórpathname
, np./café
, zostanie automatycznie znormalizowany do postaci/caf%C3%A9
. Znaki Unicode w plikuhostname
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 sprawia, że automatyczne kodowanie znaków Unicode w tych grupach jest trudne i niebezpieczne. 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 URLPattern
w 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 podstawionymi 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 wzorów, mogą być budowane na podstawie tego typu danych jako elementu prymitywnego.
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ów i pobieranie wstępne w ramach spekulacji.
Podziękowania
Pełną listę podziękowań znajdziesz w pierwotnym dokumencie z informacjami.