Menu

URL i query string w JavaScript: URL i URLSearchParams

Jak parsować, budować i modyfikować adresy URL w JavaScript za pomocą API URL i URLSearchParams, bez wyrażeń regularnych i bez błędów w przypadkach brzegowych.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Przestań parsować URL sztuczkami na stringach

Zanim pojawiło się API URL, adresy cięło się przez split('?'), wyrażenia regularne i nadzieję. Zwykle działało, dopóki wartość nie zawierała &, =, spacji albo znaku spoza ASCII, a wtedy przestawało. Zarówno przeglądarka, jak i Node mają porządny parser. Korzystaj z niego.

Jedno wywołanie i każda część adresu jest już rozdzielona i poprawnie zdekodowana. Przy niepoprawnych danych konstruktor rzuca TypeError, a zwykle właśnie tego chcesz: bezsensowny URL powinien głośno zawieść, zamiast po cichu produkować bzdury dalej w kodzie.

Odczyt parametrów zapytania

Każdy URL ma właściwość .searchParams, czyli obiekt URLSearchParams, który umie czytać i zapisywać query string:

Kilka rzeczy, na które warto zwrócić uwagę:

  • Wartości wracają już zdekodowane. ?name=Ada%20Lovelace daje "Ada Lovelace".
  • Wszystko jest stringiem. "2" to nie 2. Jeśli potrzebujesz liczby, zamień przez Number().
  • Powtórzone klucze są dozwolone. get zwraca pierwsze dopasowanie, getAll zwraca wszystkie.
  • Brakujące klucze zwracają null, a nie undefined, więc ?? "default" dobrze z nimi działa.

Budowanie query stringa

Query string możesz zbudować od zera przez URLSearchParams, bez ręcznego escapowania i bez łączenia przez &:

Albo utworzyć go z obiektu: działa dowolny iterowalny zbiór par [key, value], a także zwykły obiekt:

set a append: set zastępuje istniejącą wartość dla danego klucza, append dodaje kolejną. Używaj append, gdy klucz może się zasadnie powtarzać (tagi, filtry), a set dla parametrów o pojedynczej wartości.

Modyfikowanie URL

Ponieważ URL to żywy obiekt, zmiana searchParams automatycznie aktualizuje .search i .href:

To idiomatyczny sposób dodawania parametru zapytania do istniejącego adresu. Bez sprawdzania, czy URL ma już ?, i bez zastanawiania się, czy dokleić & czy ?.

W ten sam sposób możesz zmieniać inne części adresu:

Iterowanie po parametrach

URLSearchParams jest iterowalny. for...of daje pary [key, value], są też standardowe pomocniki keys(), values() i entries():

Zauważ, że powtórzone klucze pojawiają się wielokrotnie: zobaczysz tag = web, a potem tag = beginner jako osobne wpisy. To wiernie odpowiada faktycznemu query stringowi.

Jeśli chcesz zwykły obiekt do szybkiego wypisania przy debugowaniu, zadziała Object.fromEntries, ale scala on powtórzenia i zostawia tylko ostatnią wartość:

Do debugowania wystarczy. Źle, jeśli jakikolwiek klucz może się powtarzać.

Względne adresy potrzebują bazy

Samo new URL("/search?q=js") rzuca błąd: ścieżka względna nie jest sama w sobie poprawnym adresem URL. Przekaż bazę jako drugi argument:

Reguły rozwiązywania są takie same, jakich przeglądarki używają dla <a href>: początkowy / oznacza ścieżkę bezwzględną od hosta, brak ukośnika oznacza ścieżkę względną wobec bieżącej, a .. przechodzi poziom wyżej. Bardzo wygodne, gdy składasz adresy API ze skonfigurowanej bazy.

W przeglądarce window.location.href to gotowa baza do parsowania adresu bieżącej strony:

const u = new URL(window.location.href);
const page = u.searchParams.get("page") ?? "1";

Obsługa niepoprawnych adresów

Konstruktor URL rzuca błąd przy źle sformatowanych danych. To przydatne, ale oznacza, że potrzebujesz try/catch przy parsowaniu wszystkiego, co wpisał użytkownik albo przysłał zewnętrzny system:

Nowoczesne środowiska udostępniają też URL.canParse(input), czyli sprawdzenie zwracające boolean, które pozwala uniknąć zabawy z try/catch, gdy chcesz tylko walidować:

Mały działający przykład

Wszystko razem: odczytaj bieżące filtry z adresu, zmień je i utwórz nowy URL, na który można przejść:

Przekazanie null usuwa parametr. Każda inna wartość go ustawia albo nadpisuje. W takiej czy innej formie napiszesz ten wzorzec za każdym razem, gdy budujesz interfejs filtrów, paginację albo deep linki.

Co warto zapamiętać

  • new URL(string) rozkłada adres na nazwane części. Przy bzdurach rzuca błąd.
  • url.searchParams to URLSearchParams: używaj get, getAll, set, append, delete, has.
  • Kodowanie dzieje się samo. Nie sięgaj po encodeURIComponent, chyba że budujesz stringi ręcznie.
  • Przekaż bazowy URL jako drugi argument, żeby rozwiązać ścieżki względne.
  • URL.canParse (albo try/catch) to twoje narzędzie do walidacji niezaufanych danych.

Za każdym razem, gdy kusi cię podzielenie adresu przez .split('?') albo wyłowienie parametru zapytania regexem, sięgnij zamiast tego po te API. Są krótsze, poprawne i już wbudowane w środowisko.

Najczęściej zadawane pytania

Jak sparsować URL w JavaScript?

Przekaż string do konstruktora URL: const u = new URL('https://example.com/path?x=1'). Powstały obiekt udostępnia protocol, host, pathname, search, hash oraz pomocnika searchParams. Przy niepoprawnych adresach rzuca błąd, więc przy parsowaniu niezaufanych danych opakuj go w try/catch.

Jak odczytać parametr z query stringa w JavaScript?

Użyj url.searchParams.get('name'). Zwraca zdekodowaną wartość albo null, jeśli parametru nie ma. Dla parametrów, które mogą się powtarzać (?tag=a&tag=b), użyj searchParams.getAll('tag'), żeby dostać wszystkie wartości jako tablicę.

Czym różni się URL od URLSearchParams?

URL parsuje i reprezentuje cały adres: protokół, host, ścieżkę, zapytanie, hash. URLSearchParams to tylko część z query stringiem i możesz go używać samodzielnie do budowania albo parsowania stringów w stylu a=1&b=2. Każda instancja URL ma właściwość .searchParams, która jest obiektem URLSearchParams powiązanym z tym adresem.

Czy parametry zapytania trzeba kodować ręcznie?

Nie. URLSearchParams automatycznie koduje klucze i wartości, gdy wywołujesz set, append albo odczytujesz string. Poprawnie obsługuje spacje, &, = i Unicode. Po encodeURIComponent sięgaj tylko wtedy, gdy budujesz string ręcznie, a zwykle nie powinieneś tego robić.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ