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 rozdílnými původy (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 bez ztráty bezpečnosti.
Origin a Same-Origin Policy: základní pojmy
- Origin = kombinace
scheme://host:port(např.https://app.example.com:443). - Same-Origin Policy brání skriptům načteným z jednoho původu číst citlivé odpovědi z jiného původu.
- CORS umožní kontrolované prolomení této bariéry přes deklarativní hlavičky 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 nedostane tělo, konzole vypíše chybu).
- Server cílového zdroje rozhoduje, komu (kterému původu) a za jakých podmínek poskytne přístup pomocí CORS hlaviček.
- CDN/Proxy může měnit hlavičky, cachovat preflight odpovědi a ovlivnit chování (pozor na
Vary).
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 nestandardních hlaviček. - Preflight: prohlížeč nejprve vyšle
OPTIONSs 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 auth/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í původ.
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 původem (konkrétníhttps://example.comnebo*u ne-credentialed požadavků).Access-Control-Allow-Methods: metody povolené při preflightu (GET, POST, PUT, DELETE, OPTIONS…).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é mohou být čitelné z JS (bez toho vidí pouze safe list).Access-Control-Allow-Credentials:truepokud jsou povoleny cookies/pověření.Access-Control-Max-Age: čas, během kterého může prohlížeč cachovat výsledek preflightu (snížení latence; prohlížeče mají vlastní horní limity).Vary: Origin: extrémně důležité u CDN – odpověď se má lišit podleOrigin. Bez toho hrozí cache poisoning nebo únik hlaviček.
Životní cyklus preflightu krok za krokem
- JS (např.
fetch) chce provéstPUTs hlavičkouAuthorization. - Prohlížeč odešle
OPTIONSna stejnou URL s hlavičkamiOriginaAccess-Control-Request-*. - Server odpoví např.
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 provede 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é původy a přidalVary: Origin. - CDN před API: nechte CDN respektovat a přeposílat
Originna původní server; cachujte bezpečně podleVarya zvažte cachová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 původu s whitelistem: server zkontroluje
Origin, pokud je v seznamu, vrátíAccess-Control-Allow-Origins touto 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. - Minimalizace preflightu: preferujte simple metody a hlavičky; posílejte JSON jako
text/plainpouze pokud to bezpečnostní politika dovoluje a víte, co děláte. Častěji je lepší akceptovat preflight a správně ho cachovat.
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 per-origin politiku).
Credentialed pouze pro app: 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 mezikrok odstraní hlavičky nebo změní protokol/host/port. Ideálně odpovídejte přímo bez 302/301, zejména na preflight.
- CDN cache: vždy uvažujte
VarynaOrigina potenciálně i naAccess-Control-Request-*u preflightu. - ETag a podmíněné požadavky (
If-None-Match) fungují s CORS, ale pouze pokud se zachovají CORS hlavičky i u 304.
Bezpečnostní souvislosti: CORS ≠ autentizace
- CORS je mechanismus prohlížeče; nenahrazuje autentizaci ani autorizaci. Server musí stále validovat tokeny, session a ACL.
- Nikdy nepovolujte
*spolu 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é vektory (izolace, čitelnost, cross-origin embedding).
Vliv 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é texty, FAQ) raději renderujte SSR/SSG a nevazujte je na runtime CORS volání.
- Structured Data: netahajte JSON-LD přes cross-origin runtime fetch; vložte ho 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 asset doméně, jinak embed komponenty v SPA mohou zobrazit „broken“ stav.
- Výkon: preflight přidává RTT; při vysokém podílu CORS volání roste TTI a zhoršují se Core Web Vitals. Zvažte slučování API, HTTP/2/3, cachování preflightu a same-origin proxy.
Diagnostika a testování
- DevTools → Síť: filtrujte
OPTIONS, zkontrolujte přítomnost správných CORS hlaviček na preflight i na hlavní odpovědi. - curl: simulujte preflight např. 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ý původ; 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í původ místo
*a ponechteAllow-Credentials: true. - Preflight bloková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 u 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. - Příliš široké Allow-Headers/Methods – zužujte seznam na nezbytné hodnoty, snižujete útokový povrch.
Optimalizace výkonu: jak snížit CORS latenci
- Sláčujte volání a preferujte
GETpro čitelné zdroje s agresivním cache-control. - Pro preflight použijte rozumné
Access-Control-Max-Agea zvažte jeho cachování na CDN. - Přesuňte API pod stejný původ (reverse proxy,
/apina téže doméně), kde je to možné. - Minimalizujte vlastní hlavičky;
Authorizationje častý spouštěč preflightu – zvažte alternativní modely (např. cookie sSameSitepodle potřeby a CSRF ochranou), ale vždy s ohledem na bezpečnost.
Specifika cookies a SameSite
- Pro cross-site cookies je často potřeba
SameSite=None; Secure. Jinak prohlížeč cookie nepošle, i když CORS povoluje pověření. - 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
- Web fonty vyžadují správné CORS hlavičky na asset doméně (
Access-Control-Allow-Origin), jinak mohou být zablokovány. - Při
<img>načtení proběhne, ale čtení pixelových dat z canvasu bez CORS vede k taintnutému canvasu (ochrana soukromí). - Video a audio streamy mohou vyžadovat 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: metriky pro
OPTIONStraffic, chybovost a preflight cache hit rate na CDN.
Checklist pro bezpečné zavedení CORS
- Máte explicitní seznam povolených původů (včetně wildcardů pro subdomény,



























