Moderní tvorba webových aplikací

O webu

Query string v URL

Řetězec dotazu je část URL za otazníkem obsahující nejrůznější parametry.

10 minut
https://example.com/produkty?orderBy=price

Obsah query stringu se obvykle zapisuje ve tvaru parametr=hodnota a více těchto dvojic se oddělí ampersandem (&):

https://example.com/produkty?orderBy=price&sort=desc

Historicky existovala v HTML značka <isindex>, která umožnila zadat uživateli vstup a ten se potom poslal na server za otazníkem.

Server tak mohl nabídnout například vyhledávání.

Je dost možné, že právě proto se tyto parametry v URL někdy označují i jako search params. A v JavaScriptu se dají získat z window.location.search nebo moderněji z URLSearchParams.

Svého času se tyto parametry v URL využívaly v PHP aplikacích i pro kompletní routování. Celá aplikace klidně mohla být jediný soubor index.php, který přes obsah v URL za otazníkem rozhodoval, co se má vykreslit.

https://example.com?page=kontakt

Postupem času se přešlo k hezčím URL, kde jsou tyto parametry nenesoucí přílišnou hodnotu vypuštěny.

https://example.com/kontakt

Parametry v URL se tak používají zejména pro vyhledávání, filtrování, stránkování, předávání identifikátorů nebo invalidace cache.

https://www.google.com/search?q=je+cas

Standardy a základy

Formát URL popisuje RFC 3986 a moderní chování prohlížečů sjednocuje WHATWG URL Standard.

V JavaScriptu je k dispozici rozhraní URL a URLSearchParams. Pro kódování existuje encodeURIComponent pro jednotlivé hodnoty a encodeURI pro celé URL.

Kódování hodnot

  • Mezery mohou být kódovány jako %20.
  • Diakritika a Unicode se kódují percent-encodingem (%C4%8D je č apod.).

Struktura parametrů

Pořadí klíčů může mít teoreticky vliv na funkci, ale nebývá to moc zvykem. Pro maximální stabilitu je vhodné klíče při serialisaci řadit.

https://example.com/items?color=red&color=blue
https://example.com/items?tags[]=a&tags[]=b
  • Klíče i hodnoty jsou case-sensitive.
  • Duplicitní klíče mohou značit pole.
  • Hranaté závorky a podobně v názvech klíčů (tags[], filter[price][min]) jsou konvence pro zápis polí, ale prohlížeč je nějak speciálně neinterpretuje.
https://example.com/items?color=red&color=blue
https://example.com/items?tags=a,b
https://example.com/items?filters=%5B%22a%22,%22b%22%5D
https://example.com/search?filter%5Bprice%5D%5Bmin%5D=100&filter%5Bprice%5D%5Bmax%5D=200

Prázdné hodnoty a přepínače

  • Přítomnost klíče bez hodnoty může znamenat zapnutý přepínač (?debug).
  • ?q= je prázdná hodnota, ?q je jen přítomný klíč.
const params = new URL(location.href).searchParams;
params.has('debug');
params.get('q') === '';

Vnořené struktury

Klíče typu filter[price][min] nejsou standardizované; klient i server se musí domluvit na stejném parsování. Prohlížeč je vrací jako stringové klíče.

Pole

K úvaze je, jak řešit pole. Existují zpravidla 3 možnosti:

  1. Duplicitní klíče representují pole (getAll je načte všechny).
  2. Jednotlivé položky pole se rozdělí třeba podle čárky.
  3. Pole se do URL dává jako serialisovaný JSON.

1) Duplicitní klíče

Kompatibilní se URLSearchParams, zachová pořadí.

https://example.com/products?color=red&color=blue&color=green
const url = new URL('https://example.com');
const params = url.searchParams;
const colors = params.getAll('color');
  • Výhody: jasná semantika, podpora getAll, stabilní pořadí.
  • Nevýhoda: duplikování parametrů v URL zbytečně prodlužuje délku.

2) Oddělování čárkou

Úsporné, ale naráží na kolize s oddělovačem a vyžaduje důsledné kódování.

https://example.com/products?color=red,blue,green
const params = new URL(location.href).searchParams;
const values = (params.get('color') || '')
  .split(',')
  .filter(Boolean)
  .map(decodeURIComponent);

Sestavení URL:

const colors = ['light blue', 'red'];
const value = colors.map(encodeURIComponent).join(',');
const url = new URL('https://example.com');
url.searchParams.set('color', value);
url.toString();
  • Pro: jediný klíč, kratší než JSON.
  • Proti: hodnoty nesmí obsahovat oddělovač bez kódování; křehké při ruční editaci.

3) JSON

Umožní libovolně komplexní struktury, ale je delší a hůře čitelný.

https://example.com/products?filters=%5B%22red%22,%22blue%22%5D
const params = new URL(location.href).searchParams;
const raw = params.get('filters');
const filters = raw ? JSON.parse(decodeURIComponent(raw)) : [];

Naopak se tato adresa vytvoří pomocí JSON.stringify.

const payload = ['red', 'blue'];
const url = new URL('https://example.com');
url.searchParams.set('filters', encodeURIComponent(JSON.stringify(payload)));
url.toString();
  • Pro: libovolné typy a vnoření.
  • Proti: delší URL, horší čitelnost, nutné parsování a ošetření chyb.

Práce s URL v JavaScriptu

JS nabízí jednoduché rozhraní pro práci s parametry v URL:

const url = new URL('https://example.com/search?q=je+cas');
url.searchParams.get('q');
url.searchParams.append('page', '2');
url.searchParams.set('sort', 'desc');
url.searchParams.getAll('tag');
url.searchParams.delete('utm_source');
url.searchParams.sort();
url.toString();

JS knihovny

Pro běžné případy stačí URL a URLSearchParams. Pro vyšší kontrolu se hodí použít hotové řešení:

query-string

Jednoduché API, volitelný formát polí a stabilní serialisace.

import { parse, stringify } from 'query-string';

parse('?q=je+cas&tag=red&tag=blue');
stringify({ q: 'je cas', tag: ['red', 'blue'] });
stringify({ tag: ['red', 'blue'] }, { arrayFormat: 'comma' });
stringify({ a: 'c', z: 'y', b: 'f' }, { sort: (a, b) => a.localeCompare(b) });

qs

Robustní parser/stringifier s podporou vnořených struktur přes hranaté závorky, ochrannými limity a bohatým nastavením.

import qs from 'qs';

qs.parse('filter[price][min]=100&filter[price][max]=200&tags[]=a&tags[]=b');
qs.stringify({ filter: { price: { min: 100, max: 200 } }, tags: ['a', 'b'] });
qs.parse('a[b][c][d]=1', { depth: 2 });
qs.parse('a=1&b=2&c=3', { parameterLimit: 2 });
qs.parse('foo=bar&foo=baz', { duplicates: 'first' });

Maximální délka query parametrů

Standard pevný limit neurčuje; praktické maximum závisí na prohlížeči a infrastruktuře (proxy/CDN/webserver). Délka se počítá pro celou URL (cesta + názvy query parametrů + jejich hodnoty).

Bezpečné doporučení velikosti URL je do 2 kB pro širokou kompatibilitu. Starší prohlížeče (IE) měly limit kolem 2 kB.

Typické výchozí limity serverů bývají kolem 8 kB nebo i více. Moderní prohlížeče zvládnou mnohem více, ale limitem bývá server.

Při překročení se obvykle vrací 414 URI Too Long nebo 400 Bad Request.

U velkých dat je tak lepší použít metodu POST.

Query vs. hash

? se posílá na server, # ne.

Z toho plynou různé důsledky, kdy je co lepší použít.

Hash se tak hodí v případech, kdy je cílem přes URL sdílet data, která nemá server vidět. Nebo pro odrolování na část stránky pomocí #kotvy.

Skoro ve všech ostatních případech je lepší použít query parametr.

V URL parametrech by nemělo být nic citlivého, kde by hrozilo risiko při úniku.

Adresa se totiž může někam dostat jako referer, může být v logách nebo ji mohou uložit různé analytické nástroje. Jednou jsem takhle zachraňoval objednávky e-shopu přes Google Analytics :–)

Výkon a cache

  • CDN/cache často klíčuje podle cesty a query. Nepodstatné parametry mohou cache tříštit.
  • Někdy se toho cíleně využívá pro invalidaci cache u statických souborů (?v=123).

SEO

Z pohledu vyhledávače je každá URL s jiným obsahem query stringu samostatná stránka.

Z toho plyne risiko duplicitních stránek.

https://example.com/produkty
https://example.com/produkty?a
https://example.com/produkty?b

Všechny tyto stránky mohou vracet stejný obsah, ale vyhledávač se musí rozhodnout, kterou z nich upřednostnit.

Dokonce i následující URL mohou teoreticky vracet různý obsah:

https://example.com/produkty?orderBy=price&sort=desc
https://example.com/produkty?sort=desc&orderBy=price

Většinou se to řeší kanonickým odkazem, který jasně definuje, která varianta je preferovaná. Pomáhá také stabilizace pořadí parametrů a odstraňování šumových klíčů (např. UTM):

<link href="https://example.com/produkty" rel="canonical">

Odkazy jinam

Související články

HTML atribut download

HTML atribut download zlepšuje uživatelský dojem ze stahovaného souboru.

3 minuty

Resetování <input type=file>

Jak resetovat (odstranit) hodnotu z <input>u pro upload souborů.

3 minuty

HTML/CSS/JS identifikátor id

K čemu se hodí identifikátor, kdy ho používat a jaké znaky může obsahovat.

5 minut

Vytváření vlastních HTML značek

Je možné si kromě standardních HTML tagů vytvořit nějaké vlastní?

6 minut

Web jecas.cz píše Bohumil Jahoda, kontakt
Seznam všech článků
2013–2025