CORS issues due to incorrect API configuration

Loading

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

  1. Missing OPTIONS handling:
  • Preflight requests require proper OPTIONS method support
  1. Wildcard with credentials:
   // ❌ Won't work together
   Access-Control-Allow-Origin: *
   Access-Control-Allow-Credentials: true
  1. Incorrect headers:
  • Missing Access-Control-Allow-Headers for custom headers
  1. Wrong methods:
  • Not including all needed HTTP methods

Best Practices

  1. Configure properly on the server – This is the correct solution
  2. Use environment variables for allowed origins:
   const allowedOrigins = process.env.NODE_ENV === 'production'
     ? ['https://your-production-app.com']
     : ['http://localhost:3000'];
  1. Handle preflight requests:
   app.options('*', cors()); // Handle all OPTIONS requests
  1. 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';
}

Leave a Reply

Your email address will not be published. Required fields are marked *