![]()
Handling CORS Issues in React Applications
Cross-Origin Resource Sharing (CORS) errors are common when your React app tries to access APIs from a different domain. Here’s how to properly handle CORS configuration issues.
The Problem (CORS Errors)
// Browser console error:
// Access to fetch at 'https://api.example.com' from origin 'https://your-app.com'
// has been blocked by CORS policy
Correct Solutions
1. Server-Side Configuration (Recommended)
The proper solution is to configure your API server to include the correct CORS headers:
Node.js (Express) Example:
const express = require('express');
const cors = require('cors');
const app = express();
// Basic CORS for all routes
app.use(cors());
// Or with specific configuration
app.use(cors({
origin: 'https://your-react-app.com',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
PHP Example:
header("Access-Control-Allow-Origin: https://your-react-app.com");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
2. Proxy Server in Development
For development, configure a proxy in your React app’s package.json:
{
"proxy": "http://localhost:4000" // Your API server
}
Then make requests to /api/endpoint instead of full URLs.
3. Client-Side Workarounds (If You Control Neither Side)
Using a CORS Proxy:
const CORS_PROXY = "https://cors-anywhere.herokuapp.com/";
fetch(`${CORS_PROXY}https://api.example.com/data`)
.then(response => response.json())
.then(data => console.log(data));
With Custom Headers:
fetch('https://api.example.com/data', {
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
Common CORS Misconfigurations
- Missing OPTIONS handling:
- Preflight requests require proper OPTIONS method support
- Wildcard with credentials:
// ❌ Won't work together
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
- Incorrect headers:
- Missing
Access-Control-Allow-Headersfor custom headers
- Wrong methods:
- Not including all needed HTTP methods
Best Practices
- Configure properly on the server – This is the correct solution
- Use environment variables for allowed origins:
const allowedOrigins = process.env.NODE_ENV === 'production'
? ['https://your-production-app.com']
: ['http://localhost:3000'];
- Handle preflight requests:
app.options('*', cors()); // Handle all OPTIONS requests
- Avoid client-side workarounds in production – They’re insecure
Advanced Configuration
1. Dynamic Origin Whitelisting
const whitelist = ['https://your-app.com', 'http://localhost:3000'];
app.use(cors({
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1 || !origin) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true
}));
2. With Authentication Headers
app.use(cors({
origin: 'https://your-app.com',
allowedHeaders: ['Content-Type', 'Authorization'],
exposedHeaders: ['Authorization'],
credentials: true
}));
3. Nginx Reverse Proxy Configuration
location /api/ {
proxy_pass http://api-server;
add_header 'Access-Control-Allow-Origin' 'https://your-app.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
