DEV Community

Deep Fix
Deep Fix

Posted on

Fix CORS Errors in Node.js Fast: A Complete Guide for Developers

Introduction

Cross‑Origin Resource Sharing (CORS) errors are one of the most common roadblocks when building APIs with Node.js. In this guide we’ll walk through the root causes, quick fixes, and robust solutions so you can eliminate those frustrating browser warnings in minutes.


Why CORS Errors Appear

Browsers enforce the Same‑Origin Policy. When a web page at https://example.com tries to fetch data from http://api.myservice.local, the browser checks the response headers for Access‑Control-Allow-Origin. If the header is missing or mismatched, the request is blocked and you see:

Access to fetch at 'http://api.myservice.local/data' from origin 'https://example.com' has been blocked by CORS policy
Enter fullscreen mode Exit fullscreen mode

1️⃣ Quick Fix: Use the cors Middleware

The easiest way to enable CORS in an Express app is to add the official cors package.

const express = require('express');
const cors = require('cors');

const app = express();
// Enable CORS for all routes – you can customise the options object
app.use(cors({
  origin: '*', // <- replace '*' with specific domains in production
  methods: ['GET','POST','PUT','DELETE'],
  credentials: true
}));

app.get('/api/hello', (req, res) => {
  res.json({msg: 'CORS works!'});
});

app.listen(3000, () => console.log('Server running on http://localhost:3000'));
Enter fullscreen mode Exit fullscreen mode

Tip: For tighter security, replace origin: '*' with an array of trusted domains.


2️⃣ Manual Header Approach (No Extra Dependency)

If you prefer not to add a library, set the headers yourself.

app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', '*'); // <-- change '*' in prod
  res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  // Handle pre‑flight requests
  if (req.method === 'OPTIONS') {
    return res.sendStatus(204);
  }
  next();
});
Enter fullscreen mode Exit fullscreen mode

This works for simple APIs but can become cumbersome as the list of allowed methods or headers grows.


3️⃣ Advanced: Proxy Requests Through Nginx or a Node.js Proxy

When you cannot modify the upstream service (e.g., third‑party API), proxy the request so the browser only talks to your same‑origin server.

const { createProxyMiddleware } = require('http-proxy-middleware');

app.use('/external', createProxyMiddleware({
  target: 'https://thirdparty.com',
  changeOrigin: true,
  pathRewrite: {'^/external': ''},
  onProxyRes(proxyRes) {
    // Inject CORS headers on the fly
    proxyRes.headers['Access-Control-Allow-Origin'] = '*';
  }
}));
Enter fullscreen mode Exit fullscreen mode

Now a front‑end call to /external/data will be routed through your Node server, bypassing the original CORS restrictions.


4️⃣ Step‑by‑Step Troubleshooting Checklist

  1. Check the response headers – Use Chrome DevTools → Network → Response Headers.
  2. Verify the request method – OPTIONS pre‑flight must return 204 or 200 with proper headers.
  3. Confirm the origin – The value of Access-Control-Allow-Origin must match the request’s Origin header (or be *).
  4. Look for middleware ordering issuesapp.use(cors()) must be placed before route definitions.
  5. Inspect server logs – Some frameworks silently drop headers on errors.
  6. Test with a curl command to see raw headers:
   curl -i -X OPTIONS http://localhost:3000/api/hello -H "Origin: https://example.com" -H "Access-Control-Request-Method: GET"
Enter fullscreen mode Exit fullscreen mode

5️⃣ Deploy‑Ready Configuration

Below is a production‑ready Express setup that:

  • Whitelists specific domains.
  • Handles credentials securely.
  • Logs CORS activity for audit.
const express = require('express');
const cors = require('cors');
const morgan = require('morgan');

const whitelist = ['https://app.example.com', 'https://admin.example.com'];
const corsOptions = {
  origin: (origin, callback) => {
    if (!origin || whitelist.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error('Not allowed by CORS'));
    }
  },
  credentials: true,
  methods: ['GET','POST','PUT','DELETE','OPTIONS'],
  allowedHeaders: ['Content-Type','Authorization']
};

const app = express();
app.use(morgan('combined'));
app.use(cors(corsOptions));

app.get('/api/status', (req, res) => {
  res.json({status: 'ok'});
});

app.listen(8080, () => console.log('Production server listening on :8080'));
Enter fullscreen mode Exit fullscreen mode

Conclusion

CORS errors are not a dead‑end; they’re a signal that your API needs clearer communication with the browser. By leveraging the cors middleware, setting headers manually, or proxying requests, you can resolve the issue quickly and keep your development pipeline moving.

Ready to accelerate your fix? Download the pre‑configured script here, or explore the full toolbox with Get the complete patch tool. For a deeper dive, Access the full repository fix and integrate it into your CI/CD workflow.

Top comments (0)