My frontend on https://app.example.com calls https://api.example.com and the browser says "blocked by CORS policy: No 'Access-Control-Allow-Origin' header". How do I configure it correctly, including preflight?
DEV3 Developer Forum
How do I fix a CORS error by adding the right headers in Nginx or Apache?
Ask a question
Every post is reviewed first. Usually reviewed within 24 hours.
dev3 ·
0
1 reply
dev3 · Accepted answer
CORS is enforced by the browser. The server must answer with headers that allow the requesting origin. The fix belongs on the API side (the app framework is usually the best place, but it can be done in the web server).
What a browser needs
- Simple requests:
Access-Control-Allow-Originin the response. - Requests with JSON bodies, custom headers like
Authorization, or methods like PUT/DELETE trigger a preflightOPTIONSrequest, which must return 2xx withAccess-Control-Allow-MethodsandAccess-Control-Allow-Headers.
Nginx (allow one specific origin, never a blind * with credentials):
location /api/ {
if ($http_origin = "https://app.example.com") {
set $cors_origin $http_origin;
}
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Vary Origin always;
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Vary Origin always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
add_header Access-Control-Max-Age 86400;
return 204;
}
proxy_pass http://127.0.0.1:3000;
}
Apache: with mod_headers:
Header always set Access-Control-Allow-Origin "https://app.example.com"
Header always set Access-Control-Allow-Headers "Authorization, Content-Type"
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Pitfalls
- Duplicate headers: if both your app and Nginx add
Access-Control-Allow-Origin, browsers reject the response. Set it in one place. alwaysis needed so headers are also sent on error responses (401, 500), otherwise the browser reports CORS instead of the real error.- With cookies, use
Access-Control-Allow-Credentials: trueand an explicit origin (not*), and setcredentials: 'include'on the client. - Redirects on preflight fail; call the final URL.
Test with curl -i -X OPTIONS -H "Origin: https://app.example.com" -H "Access-Control-Request-Method: POST" https://api.example.com/api/x, or use the CORS checker.
0