CORS v kontextu webu: proč existuje a co řeší
CORS (Cross-Origin Resource Sharing) je HTTP mechanismus, který umožňuje bezpečné sdílení zdrojů mezi různými zdroji (origins). Opírá se o hlavičky v požadavcích a odpovědích, které prohlížeč respektuje při čtení dat z jiné domény, subdomény, portu nebo protokolu. CORS rozšiřuje tzv. Same-Origin Policy (SOP) tak, aby webové aplikace mohly přistupovat k API a statickým zdrojům napříč doménami, aniž by došlo ke kompromitaci bezpečnosti.
Origin a Same-Origin Policy: základní pojmy
- Origin = kombinace
scheme://host:port(např.https://app.example.com:443). - Same-Origin Policy zabraňuje skriptům načteným z jednoho zdroje číst citlivé odpovědi z jiného zdroje.
- CORS umožňuje kontrolované prolomení této bariéry prostřednictvím deklarativních hlaviček na straně serveru.
Aktéři a odpovědnosti
- Prohlížeč vynucuje pravidla CORS a v případě porušení zablokuje přístup k odpovědi (JS neobdrží tělo odpovědi, v konzoli se zobrazí chybová hláška).
- Server cílového zdroje rozhoduje, komu (kterému originu) a za jakých podmínek poskytne přístup pomocí CORS hlaviček.
- CDN/Proxy může měnit hlavičky, kešovat preflight odpovědi a ovlivnit chování (pozor na
Varyhlavičku).
Typy požadavků: jednoduché, preflight a credentialed
- Jednoduché požadavky (bez preflightu): metody
GET,HEAD,POSTs bezpečnými simple hlavičkami (např.Accept,Content-Types hodnotami typuapplication/x-www-form-urlencoded,multipart/form-datanebotext/plain), bez vlastních ne-standardních hlaviček. - Preflight: prohlížeč nejprve odešle
OPTIONSpožadavek s hlavičkamiOrigin,Access-Control-Request-Methoda případněAccess-Control-Request-Headers. Server musí odpovědět s povolením, jinak hlavní požadavek nebude proveden. - Credentialed (s pověřeními): pokud klient posílá cookies/HTTP autentizaci/klientské certifikáty (
fetchscredentials: "include"), server musí odpovědětAccess-Control-Allow-Credentials: truea nesmí použítAccess-Control-Allow-Origin: *; musí uvést konkrétní origin.
Klíčové hlavičky CORS a jejich význam
Origin: automaticky přidávaná klientem; identifikuje původ volajícího.Access-Control-Allow-Origin: odpověď serveru s povoleným originem (konkrétníhttps://example.comnebo*u ne-credentialed požadavků).Access-Control-Allow-Methods: metody povolené u preflightu (GET, POST, PUT, DELETE, OPTIONSa další).Access-Control-Allow-Headers: ne-simple hlavičky povolené v hlavním požadavku (např.Authorization, X-Requested-With).Access-Control-Expose-Headers: seznam hlaviček, které jsou čitelné z JS (jinak je vidět pouze safe list).Access-Control-Allow-Credentials:true, pokud jsou povoleny cookies/pověření.Access-Control-Max-Age: čas, po který může prohlížeč kešovat výsledek preflightu (snižuje latenci; prohlížeče mají vlastní horní limity).Vary: Origin: velmi důležité u CDN – odpověď se má lišit dleOrigin. Bez tohoto riskujete cache poisoning nebo únik hlaviček.
Životní cyklus preflightu krok za krokem
- JS (např.
fetch) chce provéstPUTs hlavičkouAuthorization. - Prohlížeč odešle
OPTIONSpožadavek na stejnou URL s hlavičkamiOriginaAccess-Control-Request-*. - Server odpoví například
Access-Control-Allow-Origin: https://app.example.com,Access-Control-Allow-Methods: PUT,Access-Control-Allow-Headers: Authorization,Access-Control-Max-Age: 600. - Prohlížeč si výsledek preflightu dočasně zapamatuje a vykoná hlavní požadavek.
Běžné topologie: SPA, API a CDN
- SPA na doméně A volá API na doméně B: nastavte B tak, aby podle whitelistu odrážel
Access-Control-Allow-Originpouze pro známé originy a přidalVary: Origin. - CDN před API: nechte CDN respektovat a přeposílat
Originna původní server; kešujte bezpečně podleVarya zvažte kešování preflightů. - Statické assety (fonty, obrázky, video): pokud se používají napříč doménami (např. fonty), přidejte
Access-Control-Allow-Origina správnýContent-Type.
Konfigurace: návrhové vzory bez bezpečnostních děr
- Reflexe originu s whitelistem: server kontroluje
Origin, pokud je v seznamu povolených, vrátíAccess-Control-Allow-Origins danou hodnotou a doplníVary: Origin. Nikdy nereflektujte libovolnýOriginbez kontroly. - Credentialed API: použijte konkrétní
Access-Control-Allow-Origin(nikoli*) aAccess-Control-Allow-Credentials: true. OmezteAllow-MethodsaAllow-Headersna minimum nezbytné. - Minimalizace preflightu: preferujte simple metody a hlavičky; posílejte JSON jako
text/plainjen pokud to bezpečnostní politika dovoluje a rozumíte tomu. Často je lepší akceptovat preflight a správně ho kešovat.
Příklady hlaviček pro API odpovědi
Ne-credentialed, více domén přes CDN: Access-Control-Allow-Origin: *, Access-Control-Expose-Headers: ETag, Link, Vary: Origin (pokud později přejdete na politiku per-origin).
Credentialed pouze pro aplikaci: Access-Control-Allow-Origin: https://app.example.com, Access-Control-Allow-Credentials: true, Access-Control-Expose-Headers: X-RateLimit-Remaining, Vary: Origin.
Preflight odpověď: Access-Control-Allow-Origin: https://app.example.com, Access-Control-Allow-Methods: GET, POST, Access-Control-Allow-Headers: Authorization, Content-Type, Access-Control-Max-Age: 600, Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers.
Redirecty, cache a CORS
- Přesměrování mohou narušit CORS, pokud prostředník odstraní hlavičky nebo změní protokol/host/port. Ideální je odpovídat přímo bez 302/301, zejména u preflightu.
- CDN cache: vždy uvažujte o
VarynaOrigina případně i naAccess-Control-Request-*pro preflight. - ETag a podmíněné požadavky (
If-None-Match) fungují s CORS pouze pokud se CORS hlavičky zachovávají i u 304 odpovědí.
Bezpečnostní souvislosti: CORS ≠ autentizace
- CORS je mechanismus prohlížeče; nenahrazuje autentizaci ani autorizaci. Server stále musí validovat tokeny, session a ACL.
- Nikdy nepovolujte
*současně sAllow-Credentials: true. Prohlížeče to blokují; jde i o bezpečnostní princip. - Oddělte CORS od politik CSP, COOP/COEP/CORP – tyto související mechanismy řeší jiné oblasti (izolaci, čitelnost, cross-origin embedding).
Dopad na SEO, AIO/AEO a LLM optimalizaci
- Indexace a rendering: Googlebot s Web Rendering Service sice vykonává JS, ale API volání přes CORS mohou selhat a způsobit neúplný obsah. Důležitá data pro SEO (např. produktové popisy, FAQ) raději generujte SSR/SSG a nespoléhejte na runtime CORS volání.
- Structured Data: neodkazujte na JSON-LD přes cross-origin runtime fetch; vložte strukturovaná data přímo do HTML.
- AIO/AEO (odpovědi asistentů): pokud widgety (HowTo, FAQ, Product) závisí na cross-origin médiích (obrázky, video), povolte CORS na assetové doméně, jinak embed komponenty v SPA mohou zobrazit nefunkční stav.
- Výkon: preflight zvyšuje round-trip time; při vysokém podílu CORS volání se prodlužuje TTI a zhoršují Core Web Vitals. Zvažte konsolidaci API, HTTP/2/3, kešování preflightu a same-origin proxy.
Diagnostika a testování
- DevTools → Síť (Network): filtrujte
OPTIONS, kontrolujte přítomnost správných CORS hlaviček jak u preflightu, tak u hlavní odpovědi. - curl: simulujte preflight například pomocí
curl -i -X OPTIONS https://api.example.com/resource -H "Origin: https://app.example.com" -H "Access-Control-Request-Method: PUT" -H "Access-Control-Request-Headers: Authorization". - Logy serveru/CDN: zapněte logování pro
OPTIONS, sledujte cache hit/miss a chováníVary. - Monitoring: měřte procento CORS chyb v JS (window
errorhandler) a korelujte s konverzemi.
Nejčastější chyby a jejich řešení
- „No ‚Access-Control-Allow-Origin‘ header is present“ – server nevrací povolení pro daný origin; přidejte správný
Access-Control-Allow-OriginaVary: Origin. - „The value of the ‚Access-Control-Allow-Origin‘ header contains ‚*‘ when credentials flag is true“ – použijte konkrétní origin místo
*a ponechteAllow-Credentials: true. - Preflight zablokován 301/302 – odpovídejte přímo nebo přesměrujte pouze hlavní požadavek; preflight by měl dostat definitivní odpověď s CORS hlavičkami.
- Chybějící hlavičky při 304 – i 304 musí obsahovat relevantní CORS hlavičky.
- CDN odstraňuje hlavičky – povolte a přeposílejte
Origina zachovejte CORS hlavičky na edge serverech. - Příliš široké Allow-Headers/Methods – omezte seznam na nezbytné hodnoty, čímž snížíte útokový povrch.
Optimalizace výkonu: jak snížit latenci CORS
- Seskupujte volání a preferujte
GETu čitelných zdrojů s agresivním cache-control. - Pro preflight použijte rozumnou hodnotu
Access-Control-Max-Agea zvažte jeho kešování na CDN. - Přesuňte API pod stejný origin (reverse proxy,
/apina stejné doméně), pokud je to možné. - Minimalizujte vlastní hlavičky;
Authorizationčasto spouští preflight – zvažte alternativní modely (např. cookie sSameSitenastavením a CSRF ochranou), vždy však s ohledem na bezpečnost.
Specifika cookies a SameSite
- Pro cross-site cookies je obvykle nutné
SameSite=None; Secure. Jinak prohlížeč cookie nepošle, i když CORS povoluje credentials. - Nezapomeňte sladit doménu cookie (
Domain) s tím, jak ji chcete používat napříč subdoménami.
Fonty, obrázky a média napříč doménami
- Webové fonty vyžadují správné CORS hlavičky na assetové doméně (
Access-Control-Allow-Origin), jinak může dojít k jejich zablokování. - Při načítání pomocí
<img>proběhne načtení, ale čtení pixelových dat z canvasu bez CORS povolení vede k znečištění canvasu (ochrana soukromí). - Video a audio streamy mohou potřebovat kompatibilní CORS i pro
Rangepožadavky a správné MIME typy.
Integrace do vývojového procesu
- Infra jako kód: definujte CORS politiky v Nginx/Apache/CloudFront/S3 konfiguraci jako součást repozitáře.
- Testy: přidejte integrační testy, které ověřují přítomnost správných hlaviček pro běžné i preflight scénáře.
- Observabilita: sledujte metriky pro



























