Vestavěná třída URL poskytuje pohodlné rozhraní pro vytváření a analýzu adres URL.
Neexistují žádné síťové metody, které by přesně vyžadovaly URL
objekt, struny jsou dost dobré. Technicky tedy nemusíme používat URL
. Ale někdy to může být opravdu užitečné.
Vytvoření adresy URL
Syntaxe pro vytvoření nového URL
objekt:
new URL(url, [base])
url
– úplná adresa URL nebo jediná cesta (pokud je nastavena základna, viz níže),base
– volitelná základní adresa URL:pokud je nastavena aurl
argument má pouze cestu, pak se URL vygeneruje vzhledem kbase
.
Například:
let url = new URL('https://javascript.info/profile/admin');
Tyto dvě adresy URL jsou stejné:
let url1 = new URL('https://javascript.info/profile/admin');
let url2 = new URL('/profile/admin', 'https://javascript.info');
alert(url1); // https://javascript.info/profile/admin
alert(url2); // https://javascript.info/profile/admin
Můžeme snadno vytvořit novou URL na základě cesty relativní k existující URL:
let url = new URL('https://javascript.info/profile/admin');
let newUrl = new URL('tester', url);
alert(newUrl); // https://javascript.info/profile/tester
URL
objekt nám okamžitě umožňuje přístup k jeho komponentám, takže je to pěkný způsob, jak analyzovat adresu URL, např.:
let url = new URL('https://javascript.info/url');
alert(url.protocol); // https:
alert(url.host); // javascript.info
alert(url.pathname); // /url
Zde je cheatsheet pro komponenty URL:
href
je úplná adresa URL, stejně jakourl.toString()
protocol
končí dvojtečkou:
search
– řetězec parametrů, který začíná otazníkem?
hash
začíná znakem hash#
- může tam být také
user
apassword
vlastnosti, pokud je přítomna autentizace HTTP:http://login:[email protected]
(výše nenabarvené, málo používané).
URL
objektů k síťovým (a většině dalších) metod namísto řetězce
Můžeme použít URL
objekt v fetch
nebo XMLHttpRequest
, téměř všude, kde se očekává řetězec URL.
Obecně URL
objekt lze předat libovolné metodě místo řetězce, protože většina metod provede převod řetězce, který změní hodnotu URL
objekt do řetězce s úplnou URL.
SearchParams “?…”
Řekněme, že chceme vytvořit adresu URL s danými parametry vyhledávání, například https://google.com/search?query=JavaScript
.
Můžeme je poskytnout v řetězci URL:
new URL('https://google.com/search?query=JavaScript')
…Ale parametry je třeba zakódovat, pokud obsahují mezery, jiná písmena než latinka atd. (více o tom níže).
Takže pro to existuje vlastnost adresy URL:url.searchParams
, objekt typu URLSearchParams.
Poskytuje pohodlné metody pro parametry vyhledávání:
append(name, value)
– přidejte parametr oname
,delete(name)
– odstraňte parametr oname
,get(name)
– získat parametr pomocíname
,getAll(name)
– získat všechny parametry se stejnýmname
(to je možné, např.?user=John&user=Pete
),has(name)
– zkontrolujte existenci parametru pomocíname
,set(name, value)
– nastavit/nahradit parametr,sort()
– řazení parametrů podle názvu, zřídka potřeba,- …a je také iterovatelný, podobně jako
Map
.
Příklad s parametry, které obsahují mezery a interpunkční znaménka:
let url = new URL('https://google.com/search');
url.searchParams.set('q', 'test me!'); // added parameter with a space and !
alert(url); // https://google.com/search?q=test+me%21
url.searchParams.set('tbs', 'qdr:y'); // added parameter with a colon :
// parameters are automatically encoded
alert(url); // https://google.com/search?q=test+me%21&tbs=qdr%3Ay
// iterate over search parameters (decoded)
for(let [name, value] of url.searchParams) {
alert(`${name}=${value}`); // q=test me!, then tbs=qdr:y
}
Kódování
Existuje standard RFC3986, který definuje, které znaky jsou v adresách URL povoleny a které ne.
Ty, které nejsou povoleny, musí být zakódovány, například písmena a mezery jiné než latinky – nahrazené jejich kódy UTF-8 s předponou %
, například %20
(mezera může být kódována +
, z historických důvodů, ale to je výjimka).
Dobrou zprávou je, že URL
objekty to vše zvládají automaticky. Pouze dodáme všechny parametry nezakódované a poté převedeme URL
na řetězec:
// using some cyrillic characters for this example
let url = new URL('https://ru.wikipedia.org/wiki/Тест');
url.searchParams.set('key', 'ъ');
alert(url); //https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D1%81%D1%82?key=%D1%8A
Jak vidíte, obě Тест
v cestě url a ъ
v parametru jsou zakódovány.
Adresa URL se prodloužila, protože každé písmeno azbuky je v UTF-8 reprezentováno dvěma bajty, takže existují dva %..
entity.
Kódovací řetězce
Za starých časů, před URL
se objevily objekty, lidé používali řetězce pro adresy URL.
Od této chvíle URL
předměty jsou často pohodlnější, ale stále lze použít i řetězce. V mnoha případech použití řetězce zkracuje kód.
Pokud však použijeme řetězec, musíme speciální znaky zakódovat/dekódovat ručně.
K tomu jsou vestavěné funkce:
- encodeURI – zakóduje adresu URL jako celek.
- decodeURI – dekóduje jej zpět.
- encodeURIComponent – zakóduje komponentu adresy URL, jako je parametr vyhledávání, hash nebo název cesty.
- decodeURIComponent – dekóduje ji zpět.
Přirozená otázka zní:„Jaký je rozdíl mezi encodeURIComponent
a encodeURI
? Kdy bychom měli použít kterýkoli z nich?“
To je snadné pochopit, když se podíváme na adresu URL, která je na obrázku výše rozdělena do částí:
https://site.com:8080/path/page?p1=v1&p2=v2#hash
Jak vidíme, znaky jako :
, ?
, =
, &
, #
jsou povoleny v URL.
…Na druhou stranu, pokud se podíváme na jednu komponentu URL, jako je parametr vyhledávání, tyto znaky musí být zakódovány, aby nedošlo k porušení formátování.
encodeURI
kóduje pouze znaky, které jsou v URL zcela zakázány.encodeURIComponent
kóduje stejné znaky a kromě nich znaky#
,$
,&
,+
,,
,/
,:
,;
,=
,?
a@
.
Takže pro celou URL můžeme použít encodeURI
:
// using cyrillic characters in url path
let url = encodeURI('http://site.com/привет');
alert(url); // http://site.com/%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82
…Zatímco pro parametry URL bychom měli používat encodeURIComponent
místo toho:
let music = encodeURIComponent('Rock&Roll');
let url = `https://google.com/search?q=${music}`;
alert(url); // https://google.com/search?q=Rock%26Roll
Porovnejte to s encodeURI
:
let music = encodeURI('Rock&Roll');
let url = `https://google.com/search?q=${music}`;
alert(url); // https://google.com/search?q=Rock&Roll
Jak vidíme, encodeURI
nekóduje &
, protože se jedná o legitimní znak adresy URL jako celku.
Ale měli bychom kódovat &
uvnitř vyhledávacího parametru, jinak dostaneme q=Rock&Roll
– to je ve skutečnosti q=Rock
plus nějaký nejasný parametr Roll
. Ne tak, jak bylo zamýšleno.
Měli bychom tedy používat pouze encodeURIComponent
pro každý parametr vyhledávání jej správně vložit do řetězce URL. Nejbezpečnější je zakódovat název i hodnotu, pokud si nejsme absolutně jisti, že obsahuje pouze povolené znaky.
URL
Třídy URL a URLSearchParams jsou založeny na nejnovější specifikaci URI:RFC3986, zatímco encode*
funkce jsou založeny na zastaralé verzi RFC2396.
Je tam pár rozdílů, např. Adresy IPv6 jsou kódovány odlišně:
// valid url with IPv6 address
let url = 'http://[2607:f8b0:4005:802::1007]/';
alert(encodeURI(url)); // http://%5B2607:f8b0:4005:802::1007%5D/
alert(new URL(url)); // http://[2607:f8b0:4005:802::1007]/
Jak vidíme, encodeURI
nahradil hranaté závorky [...]
, to není správné, důvodem je:adresy URL IPv6 v době RFC2396 (srpen 1998) neexistovaly.
Takové případy jsou vzácné, encode*
funkce většinou fungují dobře.