
“Access to fetch at … has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present”. It is one of the most searched messages for anyone who splits the site (React, Vue) from the API (Node, Python). The short answer: the block is done by the browser, not the server, and it is lifted only if the API says, in response headers, that this site’s origin may read the response. The request reached the API; it is the browser that will not let your JavaScript see the result.
What an “origin” is
The origin is the set of protocol + domain + port. https://yourcompany.com, https://www.yourcompany.com, http://yourcompany.com and https://api.yourcompany.com are four different origins. If the site is served from one and the API from another, it is a cross-origin request, and the browser demands permission. For requests that change data or carry custom headers, it first sends a “preflight” request (OPTIONS); if the API does not answer that one properly, the real request never leaves.
Making the API allow the right origin
| The API is in… | Library | Configuration (example) |
| Express (Node.js) | cors (npm install cors) |
app.use(cors({ origin: "https://yourcompany.com" })) |
| Flask | flask-cors |
CORS(app, origins=["https://yourcompany.com"]) |
| Django | django-cors-headers |
CORS_ALLOWED_ORIGINS = ["https://yourcompany.com"] and the middleware at the top of the list |
| FastAPI | Ships with CORSMiddleware |
app.add_middleware(CORSMiddleware, allow_origins=["https://yourcompany.com"]) |
Give the exact origin of your site, with the protocol and no trailing slash. Then restart the API: Node applications, and Python ones, keep the old code until they are restarted.
The CORS error can be hiding another one. If the API returns a 500 or a 503, the error page carries no CORS headers, and the browser shows the CORS error instead of the real one. Before touching the configuration, open the API address directly (or use curl -i) and see whether it answers properly. If it does not, the problem is not CORS: a 503 on a Node.js app.
|
Do not put * out of laziness. Allowing any origin is acceptable for a public read-only API. For an API with accounts, passwords or cookies it is not: it opens the door to any site. On top of that, the browser rejects * when the request carries cookies or credentials. List the origins you actually use.
|
The solution that avoids the problem: serve the site and the API from the same origin, for instance the API on an /api path of the same domain, behind a proxy. With no cross-origin requests there is no CORS. On a VPS it comes naturally: nginx as a reverse proxy.
|
|
The API answers |
|
SEE ALSO Publishing a React or Vue site: the build folder, and the refresh that gives a 404 |
RECOMMENDED PRODUCT Web hosting with cPanel Domain and SSL included, daily backups and the panel you already know. from $6.60/mo (3-year plan, with coupon) See plans |
- 0 Users Found This Useful











