
Query string v URL
Řetězec dotazu je část URL za otazníkem obsahující nejrůznější parametry.
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:
- Duplicitní klíče representují pole (
getAll
je načte všechny). - Jednotlivé položky pole se rozdělí třeba podle čárky.
- 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.

Resetování <input type=file>
Jak resetovat (odstranit) hodnotu z <input>
u pro upload souborů.

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

Vytváření vlastních HTML značek
Je možné si kromě standardních HTML tagů vytvořit nějaké vlastní?