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 referrer. 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.

Pozor. V průběhu let 2020 a 2021 se mění chování prohlížečů a z refererů postupně odstraňuje cesta, zůstává jen doména. Výchozí politika se mění na strict-origin-when-cross-origin.

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).

Důležitá změna v roce 2020 - pouze doména

Nejrozšířenější počítač Chrome začal referery osekávat. Místo kompletní adresy posílá pouze protokol a doménu. Nadále tedy nebude možné zjistit konkrétní adresu, ze které se kliklo, pouze její protokol a doménu.

Pokud z nějakých zvláštních důvodů potřebujete nadále referer při kliknutí nadále přenášet celý, můžete to nastavit ve stránce s odkazem http hlavičkou nebo tímto meta tagem:

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

Kokrétní popis meta tagu referrer mám níže.

Pozor, musíte to nastavit na stránce s odkazem. URL téhle stránky se pak při kliknutí bude přenášet v referreru celé. Pokud se budete o totéž snažit až na stránce, které referrer jen přijímá, máte smůlu, protože k ní kompletní hodnota http protokolem vůbec nedorazí.

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 zápis:

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 referer neměla spoléhat, 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.) Nejjednodušší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, Toplist). 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ů.

Jan Barášek mě ještě upozornil na to, že skript může vyhodit chybu, pokud nebude $_SERVER("HTTP_REFERER") definován. Předchozí vypsání refereru by bylo dobré ošetřit podmínkou s funkcí issset(), která zjišťuje, jestli to je vůbec definované, a tím zajišťuje, že to celé nespadne:

<?php
if (isset($_SERVER["HTTP_REFERER"])) {
    // je to definované, může se to použít
    echo "referer je " . $_SERVER["HTTP_REFERER"];
}
else {
// není to definované
    echo "referer není definován";
}
?>

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 na origin 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, referer se pošle. 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, který je na této stránce, referer odesílat. Meta tag se tedy 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 byly funkční v prohlížečích Microsoft Edge a Safari v roce 2018, naštěstí od roku 2020 už to funguje všude víceméně stejně.

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

Kromě meta tagu můžete stejnou instrukci dát i pomocí http hlavičky Referrer Policy: s hodnotami popsanými níže.

No-referrer-when-downgrade

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

Výchozí stav do roku 2020. 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 tedy jako že downgrade.)

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

Od podzimu 2020 začíná být výchozí stav jiný než no-referrer-when-downgrade. Kvůli ochraně uživatelských údajů je možné, že výchozí hodnota v prohlížečích bude strict-origin-when-cross-origin.

No-referrer

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

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

Hodnota pro staré Safari: never. Stará hodnota: none.

Příklad http hlavičky se stejným efektem:

Referrer-policy: no-referrer;

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 v síti nevěděl, kterou adresu uživatel navštívil (což je v době šmírovacích operátorů a šmírovacích reklamních situacích skoro vždy). 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 staré 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.) Tato adresa hlavní stránky se označuje jako origin = původ, zdroj, čímž se myslí web, odkud je kliknuto. Toto nastavení meta referrer má například vyhledávání Google, takže v refereru vždy posílá pouze https://www.google.com/.

Referer origin se posílá i z https na http. To je důležitý rozdíl oproti jiným hodnotám.

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

Strict-origin

Stejná jako origin, s tím rozdílem, že z https na https stránky pošle origin, ale na http stránky vůbec nic. Z http stránek posílá origin kamkoli.

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.

Hodnota pro staré Safari: origin-when-crossorigin (bez poslední pomlčky).

Strict-origin-when-cross-origin

Tohle je důležitá hodnota, protože se kvůli bezpečnosti uživatelů stala v roce 2020 novou výchozí hodnotou. Referer tak předává většinou pouze origin, to znamená hosname webu. Bez cesty, bez parametrů. Prostě "uživatel přišel z domény", nazdar. A bude se to tak dít, i když nic nenastavíte. Aby se předávalo něco víc, musí se za stránce s odkazem nastavit jiné zde uvedené hodnoty meta tagu nebo http hlavičce Referer-policy. Tedy typicky hodnotu no-referrer-when-downgrade.

Hodnota strict-origin-when-cross-origin se od origin-when-cross-origin liší jenom tím, že na http cíl nepošle vůbec nic. Na externí https cíl pošle 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 stré Safari neexistuje.

Origin-when-downgrade neexistuje

Což mě trochu štve, protože zrovna takovou funkci bych občas 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

Velmi slušná, už se na ni téměž lze spolehnout (2021). Microsoft Edge a Safari dříve podporovala jinou sadu hodnot, což už teď nehrozí (2021). Po pravdě řečeno se mi s tím nechce patlat, abych to v těch starých verzích 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 jeden 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 ve Firefoxu:

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

Jako referer by se měla přenášet pouze hlavní stránka webu, na kterém se kliklo na tento odkaz. Zkuste funkčnost: odkaz na example.com s referrerpolicy="origin"

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 kotvu 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:

Naštěstí rreferer ani refererr neexistují.

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, aktualizace červen 2020

 

Reklama

www.webhosting-c4.cz, extra rychlý SSD webhosting s doménou v ceně
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.