What Is CORS?
CORS, or Cross-Origin Resource Sharing, is a browser security mechanism that controls whether a web page on one domain may request data from a different domain. By default, browsers block such cross-origin requests. CORS lets a server opt in by sending special HTTP headers that tell the browser which outside origins are allowed to read its responses. When you see a 'blocked by CORS policy' error, it usually means the server has not granted the calling website permission — a configuration issue, not a bug in your code.
- Stands for
- Cross-Origin Resource Sharing, a W3C/WHATWG browser standard
- Enforced by
- The browser, not the server; controlled via HTTP response headers (MDN Web Docs)
- Key header
- Access-Control-Allow-Origin names which origins may read the response
- Origin equals
- Scheme + domain + port; any difference makes a request cross-origin
- Preflight
- Some requests trigger an OPTIONS 'preflight' check before the real call (MDN)
What CORS actually is #
CORS is a rule enforced by web browsers that decides whether JavaScript running on one website is allowed to read data from a different website. Suppose a page on yourshop.com wants to fetch prices from api.supplier.com. Because those are different origins, the browser treats the request with suspicion and, by default, will not let your page read the response. CORS is the mechanism by which the supplier's server can say, 'yes, yourshop.com is allowed,' by returning specific HTTP headers. If the headers grant permission, the browser hands the data to your page; if not, it blocks access and logs a CORS error. Crucially, this is a browser behavior designed to protect users, not a flaw in your website. It only affects requests made by JavaScript in a browser — server-to-server calls are unaffected. Understanding this saves enormous frustration when an integration works from a script but fails in the browser. Our /services/web-app-development team configures CORS correctly so your front-end can talk to the APIs it needs.
What 'origin' means #
To understand CORS you have to understand 'origin,' because CORS only cares when the origin changes. An origin is the combination of three things: the scheme (http or https), the domain (example.com), and the port (like 443 or 3000). Two URLs share an origin only if all three match exactly. This trips people up constantly, because differences that look trivial still count. https://example.com and http://example.com are different origins because the scheme differs. example.com and www.example.com are different because the domain differs. And example.com:3000 differs from example.com:8080 by port. Any of these mismatches makes a request cross-origin and subject to CORS rules. Even calling your own API on a subdomain like api.example.com from www.example.com is cross-origin and needs CORS headers. Knowing this explains many baffling errors where 'it's the same website' but the browser disagrees. When we plan how your front-end and back-end communicate, our /services/web-app-development team maps these origins deliberately so the browser permits exactly the requests your site should make.
Why browsers block cross-origin requests #
The blocking behavior behind CORS exists to protect you as a user, and it stems from a long-standing browser rule called the same-origin policy. Imagine you are logged into your bank in one tab. Without cross-origin protection, a malicious site open in another tab could quietly use your browser to make requests to your bank's site and read the responses, riding on your active login. The same-origin policy stops that by default: scripts can only read responses from their own origin. CORS is the controlled exception — it lets servers deliberately share data with specific other origins when that sharing is intended and safe, without throwing the door open to everyone. So CORS is not an obstacle invented to annoy developers; it is a safety valve on a protection that guards every user's logged-in sessions. When you understand what it defends against, the errors make sense. Our /services/website-security page explains how the same-origin policy and related browser protections fit into keeping your visitors and their data safe from cross-site attacks.
How a server enables CORS #
A server opts in to cross-origin access by returning Access-Control headers on its responses, naming which origins, methods, and headers it permits. Here is a typical allow response.
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://yourshop.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400
Content-Type: application/json
# Avoid this in production for authenticated APIs:
Access-Control-Allow-Origin: * # allows ANY site to call itPreflight requests explained #
For simple requests — a basic GET, say — the browser just makes the call and checks the response headers afterward. But for requests that could change data or carry unusual headers, the browser does something extra first: a preflight. Before the real request, it quietly sends an OPTIONS request to the server asking, in effect, 'I'm about to send a POST from this origin with these headers and this method — is that allowed?' The server answers with Access-Control-Allow headers listing what it permits. Only if the preflight approves does the browser send the actual request. This happens automatically and invisibly, but it explains a common surprise: developers see two requests in their network tab for one API call, or a POST that fails while a GET succeeds. Handling the OPTIONS preflight correctly on the server is essential, because if it is not answered properly the real request never fires. Our /services/web-app-development team ensures both preflight and actual requests are configured so your app's more complex API calls go through cleanly.
Reading and fixing CORS errors #
A CORS error in the browser console usually reads something like 'Access to fetch at api.example.com from origin yourshop.com has been blocked by CORS policy.' Frustrating as it looks, it is precise: it means the server's response did not include headers granting your origin permission. The fix is almost always on the server, not the front-end — no amount of tweaking your JavaScript will help, because the browser is enforcing the server's stated policy. The server needs to return an Access-Control-Allow-Origin header naming your site's origin, and for POST or custom-header requests, it must also answer the OPTIONS preflight correctly. If you do not control the third-party server, the usual solution is to route the request through your own back-end, which is not subject to browser CORS rules. Recognizing that the message points at server configuration, not broken code, is half the battle. Our /services/web-app-development team resolves these errors by configuring headers or adding a small server-side proxy so your integration works reliably in the browser.
CORS is not a server firewall #
A dangerous misconception is that CORS protects your API from unauthorized access. It does not. CORS is enforced entirely by the browser and only restricts what browser-based JavaScript on other origins may read. It does nothing to stop a direct request from a script, a command-line tool like curl, a mobile app, or an attacker's server — none of those honor CORS at all. So if your API returns sensitive data, CORS alone will never keep it safe; you still need real authentication such as API keys or tokens, plus authorization checks on the server. Setting a permissive CORS policy does not 'open a hole' in the traditional security sense, but it also grants no protection. Treat CORS as a browser convenience for legitimate front-ends, and rely on proper authentication and rate limiting for actual security. Confusing the two leads to APIs that feel protected but are wide open to non-browser clients. Our /services/website-security team makes sure your APIs are guarded by genuine access controls, not just browser-side rules that determined attackers simply ignore.
Common CORS misconfigurations #
Because CORS is fiddly, teams under pressure often reach for shortcuts that create real problems. The most frequent is setting Access-Control-Allow-Origin to the wildcard, which permits any website to call the API from a browser; for a public, read-only feed that may be acceptable, but for anything authenticated it is reckless. Another is trying to combine that wildcard with credentials like cookies, which the standard forbids, producing confusing failures. Teams also forget to handle the OPTIONS preflight, so POST requests mysteriously fail while GETs work. Some reflect back whatever origin the request claims without checking it against an allowlist, effectively recreating the wildcard while looking safer. And developers sometimes disable CORS entirely in a browser extension to 'fix' a problem locally, masking an issue that returns in production. The correct approach is a deliberate allowlist of trusted origins and careful preflight handling. Our /services/web-app-development team configures CORS to permit exactly the origins your site needs and nothing more, avoiding both broken integrations and careless over-permissioning.
What small businesses should know #
You will likely never edit a CORS header yourself, but knowing what CORS is helps you talk to your developer and recognize what a 'blocked by CORS policy' message means. The key takeaways are simple. First, a CORS error is a configuration issue on the server providing the data, not a virus or a broken website — it is usually fixable in minutes by someone who knows where to look. Second, CORS is a browser feature that protects your visitors; it is a good thing, not an obstacle to route around carelessly. Third, CORS is not security for your own API, so never let anyone tell you a permissive CORS setting is 'safe enough' for private data. If a new feature or integration on your site fails only in the browser, this is a likely culprit and a quick fix for the right professional. If you are seeing these errors, a /free-website-audit or a message via /contact lets our team diagnose and correct the configuration quickly.
FAQ
What causes a 'blocked by CORS policy' error?
The server you are requesting data from did not return headers granting your website's origin permission to read the response. The browser then blocks access. It is a server configuration issue, not a bug in your front-end code. The fix is to add the correct Access-Control-Allow-Origin header on the server or route the call through your own back-end.
Can I fix CORS from the front-end?
Generally no. CORS is enforced by the browser based on the server's response headers, so changing your JavaScript cannot grant permission the server has not given. You must adjust the server's headers, or, if you do not control that server, proxy the request through your own back-end, which browsers do not subject to CORS.
Is CORS a security feature?
For users, yes; for your server, no. CORS protects browser users from malicious cross-site reads, but it does nothing to stop direct requests from scripts, command-line tools, or other servers, which ignore it entirely. Never rely on CORS to protect an API — use real authentication, tokens, and server-side authorization for that.
What does the wildcard mean in CORS?
Setting Access-Control-Allow-Origin to an asterisk lets any website call the resource from a browser. That can be fine for a public, read-only data feed but is risky for anything private or authenticated, and it cannot be combined with credentials like cookies. A specific allowlist of trusted origins is safer for most APIs.
What is a CORS preflight request?
For requests that could change data or use custom headers, the browser first sends an automatic OPTIONS request asking the server whether the real call is allowed. If the server responds with the right Access-Control headers, the actual request proceeds. This is why you sometimes see two requests in the network tab for one API call.
Why does my API work in Postman but not the browser?
Because tools like Postman and curl do not enforce CORS — only browsers do. Your request succeeds outside the browser and fails inside it because the server has not sent headers permitting your web page's origin. Add the correct CORS headers on the server, and the browser call will work too.
How Local Web Advisor checks this for you
Is your own website getting security & compliance right?
Our free AI audit scans your site and tells you — in plain English — exactly what to fix for security & compliance and seven other areas, with the business impact and the fix for each. No login needed to start.
Run my free website audit →Was this helpful?