CORS error: blocked by CORS policy
In short: The browser blocks the response from a foreign origin because the server has not explicitly allowed this page to access it.
In more detail: Message in the console: Access to fetch at 'https://api.example.com' from origin 'https://my-site.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. This is a protection of the browser, not the server: the request arrived but the page may not read the response.
In Depth
Why it exists
The same-origin policy prevents a page (origin A) from reading data from origin B. An origin consists of protocol, host and port. CORS lets server B give selected origins access via headers. For “non-simple” requests (JSON with Authorization, PUT/DELETE) the browser first sends a preflight request (OPTIONS).
Typical causes
- The server sends no
Access-Control-Allow-Origin. - The origin does not match (
httpvs.https,wwwvs. without, other port, typo). - The preflight (
OPTIONS) is not answered or returns 404/401. Access-Control-Allow-Headersor-Methodsdo not contain what is sent.- With cookies/credentials
Access-Control-Allow-Originmust not be*andAccess-Control-Allow-Credentials: truemust be set. - An error page (500/502) contains no CORS headers and disguises itself as a CORS error.
Solutions
- On the server set the allowed origin:
Access-Control-Allow-Origin: https://my-site.comand if needed-Methods,-Headers,-Max-Age. (Express:corspackage; Next.js: headers in route handlers/next.config.) - Answer the preflight
OPTIONSwith 204. - In development use a proxy (Vite/Next
rewrites) so the browser only addresses its own origin. - Do not use
*together with cookies; check origins against a list of allowed origins and reflect them back. - Look at the Network tab (F12): which response and which headers really came back? Browser CORS extensions only “solve” your local problem, not the users’.
See also: CORS, HTTP headers