Setting CORS at the web server level is often the cleanest approach. Your application doesn’t need to know about CORS at all — Nginx or Apache handles it before the request even reaches your app.
Here are configurations I’ve used in production that work.
Nginx#
Basic: Single Origin#
server {
listen 80;
server_name api.example.com;
location / {
add_header Access-Control-Allow-Origin "https://myapp.com";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
add_header Access-Control-Allow-Credentials "true";
add_header Access-Control-Max-Age "86400";
add_header Access-Control-Expose-Headers "X-Total-Count, X-Request-Id";
# Handle preflight
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin "https://myapp.com";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
add_header Access-Control-Allow-Credentials "true";
add_header Access-Control-Max-Age "86400";
return 204;
}
proxy_pass http://127.0.0.1:3000;
}
}Note: You need to repeat the add_header directives inside the if block because Nginx’s if directive creates a new context. Headers set outside the if don’t apply inside it. This is a well-known Nginx gotcha.