Resolving CORS Issues with Nginx Proxy Configuration
This article explains why browsers block cross‑origin requests, details the four CORS response headers, demonstrates common error scenarios, and provides step‑by‑step Nginx configuration examples—including handling pre‑flight OPTIONS requests and header inheritance—to reliably solve CORS problems.
When a front‑end site (e.g., http://localhost:8080 ) accesses a back‑end service ( http://localhost:59200 ) without proper CORS handling, browsers block the request. The article first reminds readers to verify that the back‑end does not already set CORS headers and to test the API with tools like Postman.
The four essential CORS response headers are:
Access-Control-Allow-Origin – specifies allowed request origins.
Access-Control-Allow-Headers – lists permitted custom request headers.
Access-Control-Allow-Methods – enumerates allowed HTTP methods.
Access-Control-Allow-Credentials – indicates whether cookies can be sent.
Many articles suggest simply adding these headers in Nginx, but real‑world cases often require more precise configuration. The article walks through five typical error cases, showing the exact error messages and how to adjust the Nginx config for each.
Case 1 – Missing Access-Control-Allow-Origin :
server {
listen 22222;
server_name localhost;
location / {
add_header Access-Control-Allow-Origin 'http://localhost:8080';
proxy_pass http://localhost:59200;
}
}Adding the header alone may still fail because add_header only applies to successful responses. Adding the always flag fixes it:
add_header Access-Control-Allow-Origin 'http://localhost:8080' always;Case 2 – Pre‑flight request does not receive an HTTP 200 status: The solution is to return a 204 status for OPTIONS requests.
if ($request_method = 'OPTIONS') {
return 204;
}Case 3 – Missing Access-Control-Allow-Headers for authorization :
add_header Access-Control-Allow-Headers 'authorization';Placing this inside the OPTIONS block ensures the header is sent only for pre‑flight requests.
Case 4 – Unsupported HTTP method (e.g., PUT): Add the method to Access-Control-Allow-Methods or use a wildcard.
add_header Access-Control-Allow-Methods 'PUT';Case 5 – Duplicate Access-Control-Allow-Origin values from both Nginx and the back‑end: Choose either the back‑end or Nginx to set the header, but not both.
The article also explains Nginx’s add_header inheritance rule: a directive is inherited only when the current level does not define its own add_header . Therefore, placing an add_header inside an if block prevents inheritance for the outer location.
Finally, a complete, production‑ready Nginx configuration is provided:
server {
listen 22222;
server_name localhost;
location / {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin 'http://localhost:8080';
add_header Access-Control-Allow-Headers '*';
add_header Access-Control-Allow-Methods '*';
add_header Access-Control-Allow-Credentials 'true';
return 204;
}
if ($request_method != 'OPTIONS') {
add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
add_header Access-Control-Allow-Credentials 'true';
}
proxy_pass http://localhost:59200;
}
}By following these steps, developers can reliably eliminate CORS errors when using Nginx as a reverse proxy.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.