Referer stránky

informace, odkud uživatel přišel

Když uživatel někde proklikne odkaz, může následující stránka dostat informaci o tom, kde uživatel na ten odkaz kliknul. Informace se přenáší http protokolem ve hlavičce referer. Tato informace je potom v cílové stránce k dispozici skriptům - jak serverovým skriptům (např. PHP), tak klientskému javascriptu.

Referer se také často píše se zdvojeným r jako referrer. Já to různě střídám, aby to fungovalo.

Příklad vzniku refereru - Podoba http hlavičky referer - Spolehlivost refereru - Využití refereru - HTTPs a referer - Meta tag referrer - Jak neposílat referer přes odkaz - Referer a přesměrování - Referer, nebo referrer - Referer spam - Časté dotazy

Příklad vzniku refereru

Na stránce A uživatel B prokliknul přes odkaz na stránku B. Stránka B bude mít informaci, že uživatel prokliknul ze stránky A. Této informaci se říká referer. Hodnotou refereru je A. Má tvar URL.

Stránka B tedy "ví", odkud uživatel přišel.

Referer se může posílat i při jiné akci než prokliknutí odkazu. Například při odeslání formuláře nebo načtení stránky do iframe.

Jiný příklad

Na stránce A s adresou https://www.jakpsatweb.cz/ je (dejme tomu) odkaz na B, třeba na tuto stránku. Tato stránka B má adresu https://www.jakpsatweb.cz/referer.html. Pokud uživatel odkaz proklikne, tato stránka se dozví, že referer má hodnotu https://www.jakpsatweb.cz/ (referer by mělo být URL).

Podoba http hlavičky referer

(Možno přeskočit. Http hlavičky asi ručně psát nebudete.)

Informace o refereru se přenáší v http hlavičce požadavku. Když prohlížeč žádá o dokument, rovnou přidá informaci, odkud přichází.

Příklad http požadavku:

GET /druha-stranka.html HTTP/1.1
Host: example.com
Referer: https://example.com/prvni-stranka.html

Příklad ukazuje situaci, kdy uživatel proklinul ze stránky https://example.com/prvni-stranka.html (hypoteticky). Žádá server example.com (host) o stránku, která se na serveru nachází na adrese /druha-stranka.html . Přitom říká, že referer má hodnotu předchozí stránky, tedy https://example.com/prvni-stranka.html . Druhá stránka tuto hodnotu bude moci použít.

Jak zjistit referer

Nejrychlejší metodou pro mě osobně je naťukat do řádku adresy prohlížeče tento řetězec:

javascript:alert(document.referrer)

což spustí skript, který mi aktuální referer ukáže v alert okénku. Nejrychlejší to pro mě je, protože to píšu z hlavy. Pozor, pokud to do okna prohlížeče zkopírujete, část "javascript:" se nezkopíruje. Takže tu část javascript: je nutno psát vždy.

Jinou metodou je zmáčknout F12 a v nástrojích zvolit Síť, vybrat objekt stránky a zobrazit si jeho hlavičky.

Referer je také vidět v klasicky nastaveném apachovském logu.

Spolehlivost refereru

Hlavička s refererem nemusí být vůbec přítomná. V takovém případě stránka o způsobu příchodu uživatele nic neví.

Kdy informace o refereru chybí:

Referer nemusí být správně v těchto případech:

Z toho všeho plyne, že informace o refereru je velmi nespolehlivá. Funkčnost stránek by na refereru neměla stát, jde vždy jenom o informaci navíc.

Využití refereru

Referrer v javascriptu

Využití refereru v javascriptu se dělá přes document.referrer. (Pozor, dvě r.) Nejblbějším příkladem je vyhození alertu s hodnotou refereru. Vypadá nějak takhle:

<button onclick="alert(document.referrer)">klikni a vyskočí referer</button>

Pokud stránka informaci o refereru má, v alertu ji zobrazí jako URL. Pokud ji nemá, alert bude prázdný.

Alert s referererm je blbina. Mnohem častější javascriptové použití je přidání refereru do nějakého počitadla nebo měřícího softwaru (např. Google Analytics). Do volání počitadla se přitom referrer přidává jako parametr volání. Například Toplist:

<script>
var topImg = new Image();
topImg.src = "https://www.toplist.cz/dot.asp?id=987654321&http=" + escape(document.referrer);
</script>

Co to dělá: vytvoří nový obrázek a přiřadí mu zdroj (src). Tento zdroj se sestaví z adresy serveru počitadla, z id patřícího stránkám a vyescapovaný referrer. Tento obrázek si pokusí src stáhnout, čehož si všimne server počitadla (požadavek vede na server počitadla) a zapíše si přístup do databáze. Přitom si zároveň může zapsat i ten referrer, z čehož může poznat cestu uživatele po stránkách. Escapování se používá kvůli tomu, že referer jako obecné url může obsahovat divoké znaky, které by mohly vyskládaný src přerušit.

Možná jsem zvolil zbytečně složitý příklad. Stačí, když si zapamatujete, že referer je uložený v objektu document.referrer.

Referer v PHP

Do PHP se informace o refereru z http hlavičky dostává přes objekt $_SERVER. Konkrétně je to hodnota

$_SERVER["HTTP_REFERER"]

Takže například vypsání hodnoty referera na stránku se udělá PHP instrukcí:

<?php
echo $_SERVER["HTTP_REFERER"];
?>

Jak konkrétně v serverovém skriptu referer použít? Záleží na tom, co chcete dělat. Používá se to třeba na trackbacky, na základní statistiky nebo na přesnější kontrolu příchodů.

Hledané dotazy ve vyhledávačích

V minulosti se referer používal zejména na zaznamenávaní dotazů, přes které přišli uživatelé z vyhledávačů. Referer vypadal nějak jako http://www.google.com/?q=iphone%20levně, kde to "iphone levně" byl dotaz zadaný uživatelem do Googlu. Přibližně od roku 2012 začal Google různými metodami dotazy skrývat a v Analytics místo dotazu bylo uvedeno "(not provided)" a nyní (2017) jako referer posílá pouze adresu hlavní stránky.

Seznam zatím posílá referery s dotazy jako dříve. Přišlo mi to tak zatím správně, ale uvažuji o změně podobné Googlu nebo aspoň na no-referrer-when-downgrade, zejména kvůli ochraně soukromí uživatelů.

HTTPS a referer

Jedním z cílů HTTPS je schovat informaci, o jakou přesně URL uživatel server žádá. V případě nezabezpečeného http provozovatelé sítě (operátoři, správci sítí a routerů) vidí celý http provoz otevřeně a můžou si jej přečíst včetně hlaviček. Naopak při https provozu vidí jenom to, kam provoz jde, zbytek je zakódovaný rozsypaný čaj. V něm nejsou požadované adresy vidět, což je super vlastnost https.

Na https stránkách běžně bývají odkazy na http. Když uživatel na https stránce klikne na http odkaz, následující komunikace probíhá nezakódovaně a útočník ji může vidět. Kdyby v tu chvíli viděl hlavičku referer, mohl by si v ní přečíst adresu https stránky. To je problém. Adresa https stránky má zůstat skryta, to je účel https.

Řeší se to tak, že prohlížeče v případě odkazu z https na http referer neposílají.

Různé možné stavy jsem se pokusil shrnout do tabulky.

ze stránky A na stránku B Pošle se stránce B referer?
http http Ano, referer se pošle jako vždy. Celá komunikace je otevřená, tak není co tajit.
http https Ano, referer se pošle. Útočník stejně hlavičky stránky B nevidí, jsou šifrované.
https http NE, referer se nepošle. Adresa https stránky A by byla v komunikaci s B vyzrazena provozovateli sítě.
https https Ano. Celá komunikace je šifrovaná.

Neposílání refererů při přechodu z https na http je výchozí chování současných moderních prohlížečů (a je to tak dobře). Protože takové chování ale autorům některých https stránek nevyhovuje, existují způsoby, jak nechat prohlížeč referer v nějaké formě posílat. Konkrétně jde o meta tag referrer.

Meta tag referrer

Shrnutí: prostudujte si hodnotu "origin", ostatní klidně přeskočte.

Meta tag referrer vzniknul zejména kvůli https (přijde mi to evidentní z hodnot), ale hodí se i pro obecné řízení toho, jestli se bude při kliknutí na odkaz referer odesílat. Meta tag se dává do HTML hlavičky stránky, ze které vede odkaz (v mé terminologii tedy do stránky A).

Ve specifikacích a implementacích je docela zmatek. Jestli jsem to správně pochopil, existují tři sady hodnot. Prastará, stará a současná. Pokouším se popsat současnou, ale uvádím i starou a prastarou. Prastaré hodnoty jsou stále jediné funkční v prohlížečích Microsoft Edge a Safari.

Pozor, zapisuje se s dvěma r vedle sebe: referrer. Pokud hledáte specifikaci, najdete ji pod anglickým názvem referrer policy.

No-referrer-when-downgrade

<meta name="referrer" content="no-referrer-when-downgrade">

Výchozí stav. Stránka posílá referer stejně, jako kdyby žádný meta tag zadán nebyl. (Hodnota none-when-downgrade jako downgrade zmiňuje situaci, kdy se z https protokolu proklikává na http, což je jako downgrade.)

Hodnota pro Edge a Safari: default, což ale nevadí, protože hodnotu: no-referrer-when-downgrade budou ignorovat. Stará hodnota: none-when-downgrade.

No-referrer

<meta name="referrer" content="no-referrer">

Extrémní hodnota. Referer se neposílá nikdy.

Hodnota pro Edge a Safari: never. Stará hodnota: none.

Unsafe-url

<meta name="referrer" content="unsafe-url">

Druhá extrémní hodnota. Referer se posílá vždy, tedy i v případě, že stránka s meta tagem je na https a cílová stránka je na http. Není to zrovna dobrý nápad zejména v případě, kdy je důležité, aby nikdo nevěděl, kterou adresu uživatel navštívil. Já hodnotu unsafe-url výjimečně používám v situacích, kdy je pro mě důležité, aby provozovatelé http stránek, na které odkazuji, věděli o návštěvnosti, kterou přivádím.

Hodnota pro Edge a Safari: always.

Origin

<meta name="referrer" content="origin">

Jako referer se pošle adresa hlavní stránky odkazujícího webu. (Přesněji vzato schéma, host a port.) Toto nastavení má například vyhledávání Google.

Hodnota pro Edge a Safari: origin (naštěstí stejná, takže je to použitelné všude).

Origin-when-cross-origin

<meta name="referrer" content="origin-when-cross-origin">

Jiná kompromisní hodnota. V případě prokliku na externí web (lišící se doménou, portem či protokolem) se jako referer posílá adresa hlavní stránky (jako v hodnotě "origin"). V případě prokliku na stejný web (stejný protokol, hostname i port) se přenese referer přesně celý. To je důležité pro sledování interních průchodů uživatelů webem.

Stará hodnota: origin-when-crossorigin (bez poslední pomlčky).

Existují ještě hodnoty strict-origin a strict-origin-when-cross-origin, které se od svých ne-strict verzí liší jenom tím, že na http cíl nepošlou vůbec nic. Na externí https pošlou aspoň origin.

Same-origin

<meta name="referrer" content="same-origin">

Podobné jako origin-when-cross-origin, ale v případě prokliku pryč z webu se referer vůbec neposílá. V případě prokliku uvnitř webu se posílá plné URL.

Ekvivalent této hodnoty pro Edge a Safari neexistuje.

Origin-when-downgrade neexistuje

Což mě těžce štve, protože zrovna takovou funkci bych nejvíc potřeboval. Chtěl bych na externí https cíle posílat plnou URL a na http cíle jenom origin (adresu hlavní stránky). To ale se současnými hodnotami udělat nejde.

Podpora meta tagu referrer

Docela slušná, ale nelze se na ni spolehnout. Microsoft Edge a Safari podporuje jinou sadu hodnot a po pravdě řečeno se mi s tím nechce patlat, abych to testoval.

Kromě meta tagu by mělo jít chování nastavit http hlavičkou odpovědi Referer-Policy: se stejnými hodnotami jako má content v meta tagu. Netestoval jsem.

Jak neposílat referer přes odkaz

Existuje relativně nová hodnota atributu rel v odkazu, která prohlížeči řekne, že cílové stránce nemá posílat referer.

<a href="https://www.seznam.cz/" rel="noreferrer">

Asi od roku 2016 už to funguje ve všech běžných prohlížečích, takže se na rel="noreferrer" dá spolehnout.

Pozor, dvě r. Noreferrer.

Využití odkazu bez přenášeného refereru vidím hlavně v různých administracích. Pokud potřebujete z nějakého svého adminu proklikávat na cizí weby, ale nechcete, aby provozovatelé těch webů viděli, že klikáte z nějakého adminu, tak přesně na to se rel="noreferrer" hodí.

Pokud potřebujete mít odkaz s dalšími hodnotami atributu rel, typicky například nofollow, oddělují se mezerou:

<a href="https://www.seznam.cz/" rel="noreferrer nofollow">

Referrerpolicy

Našel jsem ve specifikaci možnost nastavit u odkazu stejné hodnoty referrer policy jako u meta tagu referrer pomocí atributu referrerpolicy. Zdá se, že to funguje ve Chrome a Firefoxu:

<a href="http://example.com" referrerpolicy="origin">odkaz na example.com</a>

Zkuste funkčnost: odkaz na example.com

Referer a přesměrování

Přesměrování udělané http hlavičkami 301 a 302 zachovává referer. Příklad:

  1. Uživatel z A proklikne na B.
  2. B je serverem přesměrováno na C.
  3. Prohlížeč požádá o C. C dostává jako referer stále původní A.

V historii existovaly různé triky, jak jiným než http přesměrováním zařídit, že se referer nepřenášel. Šlo ale o využití nedokumentovaných vlastností prohlížečů. Já jsem na to například používal javascriptovou metodu location.replace. To už ale není nutné, protože lepší funkci přináší rel="noreferrer" v odkazu.

Stejně tak se referer zachová při znovunačtení stránky.

Referer se neustaví tam, kde nedochází ke komunikaci se serverem. Například při kliknutí na záložku na téže stránce se referer nezmění.

Referer, nebo referrer?

Nehodlám se účastnit gramatické války, která varianta je správně. Kromě webařů se do této války rádi zapojují angličtináři a wikipedisté (česká wikina uvádí jako správný zápis referrer, anglická naopak referer). Ale je to fuk, jde vždy o totéž. Vypozoroval jsem pravidlo:

Referer spam

Referer spam využívá faktu, že si provozovatelé webů rádi ve statistikách prohlížejí informace, odkud uživatelé přišli. Běžně tam vidí skutečné adresy stránek s odkazy a proklikávají si je, což je zajímavé. Je radost vidět stránku, která na mě odkazuje.

Spameři si udělají robota, který prochází po stránkách, ale jako referer v http hlavičce neposílá skutečné odkazující stránky, ale nějaké svoje stránky s reklamami. Provozovatelé webů takové stránky vidí ve statistikách a proklikávají je. Obvykle jsou tam pak reklamy na hosting a na optimalizaci webů, tedy věci, které mohou být pro oběti spamu relativně zajímavé.

Protože nejpoužívanější statistický software jsou Google Analytics, zaznamenal jsem snahu udělat soupis spamových webů a nějak to do Analytics importovat jako filtr. Sám to neřeším, takže víc nevím.

Časté dotazy

Dá se nějak zjistit, jakou stránku si prohlížel uživatel před mojí stránkou, ale nekliknul na odkaz?
Ne. Je to logické. Takhle by se dalo dobře šmírovat, co třeba uživatelé čtou na facebooku. Naštěstí se v takových případech referer nepřenáší.
Dá se nějak zjistit, na které stránky uživatel kliká z mé stránky? Nezajímá mě tedy odkud přišli, ale kam odcházejí.
Ano, musíte si na ale odkazy navěsit javascriptové události, které stihnou kliknutí nabonzovat nějakému vašemu sledovacímu skriptu. Většinou se to věší na událost onmousedown spíš než na onclick, aby se událost stihla zaznamenat. Jiná metoda je vést odkaz přes přesměrování, které se loguje a počítá se z toho statistika.
Ovlivňuje nějak referer, pokud se odkaz otevře do nového okna?
Ne, referer se do nového okna přenáší stejně jako do stejného okna.
Dá se nastavit, aby prohlížeč neposílal referer?
Pro Chrome a Firefox se dá stáhnout nějaký doplněk. Pro ostatní prohlížeče nevím.
Uvedené příklady mi nefungují
To se může stát, referer je nespolehlivá věc. Při přepisování dejte pozor na zápis. Má-li se psát referer, je nutné psát referer a ne referrer. A naopak jindy je třeba psát referrer se čtyřmi r.
U přístupů z Google vidím jenom https://www.google.cz, ale už ne hledaný dotaz.
Protože Google to tak chce. Nastavil si referer-policy na hodnotu origin, takže hledaný dotaz vidět není.

Publikováno 28. 12. 2017

 

Reklama

www.webhosting-c4.cz, webhosting s doménou v ceně. 20GB
o tvorbě, údržbě a zlepšování internetových stránek

Návody HTML CSS JavaScript Články Ostatní

Základy Prvky stránek Tvorba webu

Jak psát web píše Yuhů, Dušan Janovský. Kontakt.