Understanding CORS: A Simple Guide and Fixes

Outline

  1. Hook / Intro — relatable scenario of hitting a CORS error

  2. What is CORS? — simple definition

  3. Why Browsers Enforce It — the security reason

  4. How It Works — origins, request/response headers, preflight

  5. Common Causes of CORS Errors — real-world dev cases

  6. How to Fix CORS — backend, frontend, proxy solutions

  7. Best Practices & Security Notes

  8. Conclusion & Resources


Intro: The Dreaded CORS Error

You’ve just connected your frontend to a shiny new API. You hit “Refresh”... and bam!

pgsqlCopyEditAccess to fetch at 'https://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy

If you’ve been here before, you know the frustration. This is where CORS comes in.


What is CORS?

CORS (Cross-Origin Resource Sharing) is a browser mechanism that controls how web applications interact with resources from different origins.

Origin = protocol + domain + port

  • http://localhost:3000

  • https://myapp.com

By default, browsers block requests to a different origin to protect users from malicious sites.


Why Does It Exist?

Without CORS, any malicious website could silently make API calls to other sites where you’re logged in (like your bank) and read sensitive data.

CORS acts as a gatekeeper — unless the server explicitly says “yes, I trust you,” your browser says “nope.”


How CORS Works

  1. Simple Requests (e.g., GET without special headers)

    • Browser sends the request directly.

    • Server responds with a header like:

        arduinoCopyEditAccess-Control-Allow-Origin: https://myapp.com
      
    • If the header matches the requesting origin, the browser delivers the data.

  2. Preflight Requests (e.g., POST with JSON body or custom headers)

    • Browser sends an OPTIONS request first.

    • Server must respond with allowed methods, headers, and origin.

    • Only then is the real request sent.


Common Causes of CORS Errors

  • Server missing Access-Control-Allow-Origin header

  • API only allows specific domains, but you’re testing from localhost

  • Sending credentials without Access-Control-Allow-Credentials enabled

  • Using HTTP vs. HTTPS mismatches


How to Fix CORS

On the Backend (Preferred)

Add appropriate CORS headers:
Node.js + Express example

javascriptCopyEditimport express from "express";
import cors from "cors";

const app = express();
app.use(cors({ origin: "http://localhost:3000" })); // allow only your frontend

Using a Proxy

If you can’t modify the API server, you can proxy requests through your backend:

arduinoCopyEditFrontend → Your Server → Target API

This way, the browser thinks it’s same-origin.

For Local Dev Only

When running locally, CORS errors can slow you down — but you can work around them during development:

Enable CORS in the Backend (Best Way)

If you own the backend, just allow your local origin:

javascriptCopyEditapp.use(cors({ origin: "http://localhost:3000" }));

Use a Local Development Proxy

javascriptCopyEditserver: {
  proxy: {
    '/api': 'https://api.example.com'
  }
}

Use a Backend Middleware Proxy

Create a small Node server that forwards requests to the API.

Temporary Browser Extension

Chrome: “Allow CORS”
Firefox: “CORS Everywhere”
⚠ Dev-only, not for production.

Run Browser with Security Disabled

bashCopyEditchrome.exe --disable-web-security --user-data-dir="C:/chrome-dev"

⚠ Dangerous — use only for quick testing.


Best Practices

  • Never use Access-Control-Allow-Origin: * for APIs with sensitive data.

  • Use whitelists for allowed origins.

  • Always consider security over convenience.


Conclusion

CORS isn’t a bug — it’s a browser’s way of protecting users. Once you understand how it works, you can work with it instead of fighting it.

Further Reading:

0
Subscribe to my newsletter

Read articles from vamshidhar reddy directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

vamshidhar reddy
vamshidhar reddy