How to Fix CORS Errors with Nginx Proxy: Step‑by‑Step Guide
This article walks through the root causes of CORS failures when a front‑end site accesses a back‑end service, explains the four essential CORS response headers, and provides detailed Nginx configurations—including handling preflight OPTIONS requests and adding missing headers—to reliably resolve cross‑origin issues.
Preparation
Before tackling CORS, ensure the back‑end does not already set CORS headers and verify the API works with Postman. The front‑end runs at http://localhost:8080 and the back‑end at http://localhost:59200.
CORS Response Headers
Access-Control-Allow-Origin– specifies the allowed origin. Access-Control-Allow-Headers – lists permitted custom request headers (checked during preflight). Access-Control-Allow-Methods – enumerates allowed HTTP methods. Access-Control-Allow-Credentials – indicates whether cookies can be sent.
Common Errors and Fixes
Case 1: Missing Access-Control-Allow-Origin in the preflight response.
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 not work because add_header is only applied to successful responses. Append always to force the header on all responses.
add_header Access-Control-Allow-Origin 'http://localhost:8080' always;Case 2: Preflight request returns a non‑200 status (e.g., 204 is required).
if ($request_method = 'OPTIONS') {
return 204;
}Case 3: Missing Access-Control-Allow-Headers for custom headers such as authorization.
add_header Access-Control-Allow-Headers 'authorization';Place this inside the OPTIONS block so it only applies to preflight requests.
Case 4: HTTP method not allowed (e.g., PUT).
add_header Access-Control-Allow-Methods 'PUT';Alternatively use * to allow all methods, but be cautious with security.
Case 5: Multiple Access-Control-Allow-Origin values (e.g., * and a specific domain) cause a conflict. Ensure only one origin header is sent.
Robust Nginx Configuration
Below is a comprehensive configuration that handles all the above scenarios:
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' always;
}
proxy_pass http://localhost:59200;
}
}Another simpler variant places the headers outside the conditional block and only returns 204 for OPTIONS:
server {
listen 22222;
server_name localhost;
location / {
add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
add_header Access-Control-Allow-Headers '*';
add_header Access-Control-Allow-Methods '*';
add_header Access-Control-Allow-Credentials 'true';
if ($request_method = 'OPTIONS') { return 204; }
proxy_pass http://localhost:59200;
}
}These configurations ensure that the required CORS headers are always present, that preflight requests receive a 204 response, and that only a single Access-Control-Allow-Origin header is sent.
By following these steps and adapting the configuration to your specific domain and methods, you can reliably eliminate CORS errors during development and production.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java High-Performance Architecture
Sharing Java development articles and resources, including SSM architecture and the Spring ecosystem (Spring Boot, Spring Cloud, MyBatis, Dubbo, Docker), Zookeeper, Redis, architecture design, microservices, message queues, Git, etc.
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.
