Few error messages generate as much frustration as the CORS error: your JavaScript tries to fetch from another domain and the browser refuses, citing a missing "Access-Control-Allow-Origin" header. The usual reaction is to treat CORS as an obstacle invented to ruin your afternoon. It is actually a security feature, and understanding what it protects makes the fix obvious instead of infuriating.
The one-line summary that saves hours: CORS is enforced by the browser but configured on the server you are calling. You almost never fix a CORS error in your front-end code.
What the browser is protecting
Browsers enforce the same-origin policy: by default, JavaScript on one site cannot read responses from a different origin (a different domain, protocol or port). This stops a malicious page you visit from quietly reading your logged-in data from your bank in another tab. CORS — Cross-Origin Resource Sharing — is the controlled way a server can opt in to allowing specific other origins to read its responses.
So the error is the security policy working as designed. The server you are calling has not said "this origin is allowed to read my responses", so the browser blocks your JavaScript from seeing the result — even though the request may have reached the server.
Where the fix lives
Because CORS permission is granted by the responding server, the fix is a server-side header. The server must return "Access-Control-Allow-Origin" naming your origin (or a wildcard for public APIs), plus related headers for the methods and headers you use. If you own that server, you add the configuration; if you do not, you use an API that supports CORS, or route the request through your own back-end, which is not subject to the browser's same-origin policy.
This is why disabling browser security or copying random front-end snippets never truly fixes CORS — the permission simply is not yours to grant from the client.
The preflight request
For anything beyond simple requests, the browser sends a preflight: an automatic OPTIONS request that asks the server, in advance, whether the real request is allowed. Only if the server answers with the right permission headers does the browser send the actual request. This is why you sometimes see a mysterious OPTIONS call in your network tab that you never wrote — the browser added it.
Preflights are also why CORS failures can be confusing: the real request may never fire at all. Once you internalise that CORS is a browser-enforced, server-granted permission with an automatic preflight handshake, the errors stop feeling like sabotage and start reading like exactly what they are — a checklist of headers the target server needs to send.