Cross-Origin Resource Sharing (CORS) is a browser security feature that restricts web pages from making requests to a different domain than the one that served the web page. If you're building a web application where the frontend and backend are hosted on different domains or ports, you’ll encounter CORS errors unless properly configured.
This article breaks down what CORS headers are, why they are important in production, and how to configure them securely and step-by-step. We’ll also cover the pros and cons of enabling CORS, along with some SEO-focused insights.
CORS headers are HTTP headers that allow a server to define which external domains can access its resources. This helps enforce the same-origin policy in browsers, which by default blocks cross-origin requests to prevent malicious access.
CORS involves two main types of headers: those sent by the client in a request and those returned by the server in a response.
Origin
This header indicates the origin (scheme, host, and port) from which the request is initiated.
Example: Origin: https://frontend.example.com
Access-Control-Request-Method
Used in preflight requests to indicate which HTTP method will be used in the actual request.
Example: Access-Control-Request-Method: POST
Access-Control-Request-Headers
Lists any custom headers the client wants to include in the actual request.
Example: Access-Control-Request-Headers: X-Custom-Token, Content-Type
Access-Control-Allow-Origin
Specifies which origins are permitted to access the resource.
Example: Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Methods
Specifies which HTTP methods are allowed when accessing the resource.
Example: Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers
Indicates which request headers the server will accept.
Example: Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials
Indicates whether credentials (such as cookies or HTTP authentication) are allowed.
Example: Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers
Allows the client to read certain response headers that are not exposed by default.
Example: Access-Control-Expose-Headers: X-RateLimit-Remaining
Access-Control-Max-Age
Specifies how long the results of a preflight request can be cached.
Example: Access-Control-Max-Age: 86400
CORS becomes necessary in production when your frontend and backend are deployed on different origins, which is common in microservice or decoupled SPA architectures.
Without CORS headers, browsers will block requests from your frontend to your backend. This is a security feature to protect users but it must be deliberately overridden using CORS headers when the cross-origin access is legitimate and secure.
Avoid using wildcards like * in production. Instead, whitelist only the domains that should have access.
Example:
https://frontend.example.com should be explicitly listed as an allowed origin.
Nginx Configuration Example
location /api/ {
add_header 'Access-Control-Allow-Origin' 'https://frontend.example.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Allow-Credentials' 'true';
}
Express.js Middleware Example
const cors = require('cors');
app.use(cors({
origin: 'https://frontend.example.com',
methods: ['GET', 'POST'],
credentials: true
}));
Flask Example
from flask_cors import CORS
CORS(app, origins="https://frontend.example.com", supports_credentials=True)
Browsers send a preflight OPTIONS request to verify allowed methods and headers before the actual request is made.
Example in Nginx:
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://frontend.example.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
return 204;
}
Correctly implementing CORS headers is essential for applications that need to operate across multiple origins. It allows for secure cross-origin requests while maintaining browser security constraints.
Enables frontend-backend separation
Protects against unauthorized access
Required for modern web architectures
Misconfiguration can expose your API
Can be difficult to debug without proper tooling
May cause unexpected behavior if credentials or headers are not handled carefully
Always test your CORS configuration thoroughly. Avoid using wildcard origins in production when credentials are involved. Never expose sensitive headers unnecessarily. Do it at your own risk after understanding the implications.
What are the types of CORS headers and their use?
How to enable CORS in Nginx, Flask, or Express.js?
What is the role of Access-Control-Allow-Origin in CORS?
Why does my frontend app get CORS error?
How to handle preflight requests in production?
Best practices for CORS in a secure API
CORS configuration examples for production setup
What are the different types of CORS headers?
How to fix CORS error in React or Angular applications?
How to configure CORS in Nginx for production?
Why does my frontend get blocked by CORS policy?
How to handle preflight OPTIONS request in Express or Flask?
Best practices for secure CORS configuration
What is Access-Control-Allow-Origin and how does it work?
#CORS
#CORSHeaders
#WebSecurity
#CrossOriginResourceSharing
#FrontendBackendCommunication
#APISecurity
#CORSInProduction
#NginxCORS
#ExpressCORS
#FlaskCORS
#DevOpsTips
#WebApplicationSecurity
#CORS #CrossOriginResourceSharing #WebSecurity #FrontendBackend #APISecurity
#NginxCORS #ExpressCORS #FlaskCORS #CORSHeaders #WebDevTips #DevOps #ProductionReady