DEV Community

Cover image for CORS Explained: From Toy Boxes to Technical Implementation
Ismile Hossain
Ismile Hossain

Posted on

CORS Explained: From Toy Boxes to Technical Implementation

🧠 CORS Explained Like You're 5

Imagine this: You have a toy box (your website running in the browser), and you love playing with your own toys (your own data).

One day, you try to grab a toy from your friend’s toy box (another website’s data).
But your mom (the browser) stops you and says:

"Hold on! I don’t know if your friend’s parents said it’s okay for you to borrow their toys!"

This is where CORS (Cross-Origin Resource Sharing) comes in.

🧑‍🍳 The Server = Your Friend’s Parent
When you try to grab the toy, your mom doesn’t just say "yes" or "no" by herself.
She actually asks your friend’s parent (the server):

“Hey, is it okay if my kid plays with your kids’ toys?”

If your friend’s parent says:

📝 "Sure! I wrote a permission slip (CORS headers) that says it’s okay!"

Then your mom lets you take the toy and play with it. 🎉
But if your friend’s parent says:

❌ "Nope. My kids’ toys are only for them and not for anyone else."

Then your mom stops you and says:

"Sorry, no permission, no playing!"

So basically:

  • ✅ Same toy box? No problem.
  • 🚫 Different toy box? Need permission (CORS).
  • 🔒 No permission? No playing!

🔒 What is CORS?

CORS (Cross-Origin Resource Sharing) is a security feature enforced by browsers. It controls how a web page running in one origin (protocol + domain + port) can make requests to a different origin.

By default, browsers block cross-origin requests made from JavaScript for security reasons.

🌐 What is an "Origin"?

An origin includes:

  • Protocol: http:// vs https://
  • Domain: example.com vs api.example.com
  • Port: :80 vs :8080

If any of these differ, it's considered a cross-origin request and CORS rules apply.


📍 Example Scenario

You have a frontend app hosted at:

  • Frontend: https://myfrontend.com

And you try to fetch data from:

  • Backend API: https://api.othersite.com/data

Since the domains are different, this is a cross-origin request. Unless https://api.othersite.com explicitly allows it, the browser will block the request.


✅ How CORS Works

When the browser sees a cross-origin request, it may first send a preflight request (an OPTIONS request), to ask the server:

"Hey, can I make this request from https://myfrontend.com?"

If the server replies with the right headers like:

Access-Control-Allow-Origin: https://myfrontend.com
Enter fullscreen mode Exit fullscreen mode

Then the browser says, "Cool, I'm allowed to proceed." And sends the actual request.

If the header is missing or doesn't match, the browser blocks the request.


🛫 Preflight Request Flow

  • Browser: Sends OPTIONS request with details.
  • Server: Responds with CORS headers (if allowed).
  • Browser: If okay, sends the actual request.

Visual Flow Diagram
Preflight Request


📦 Sample HTTP Preflight Request

Request:

OPTIONS /data HTTP/1.1  
Origin: https://example-frontend.com  
Access-Control-Request-Method: POST  
Access-Control-Request-Headers: Content-Type
Enter fullscreen mode Exit fullscreen mode

Response:

HTTP/1.1 204 No Content  
Access-Control-Allow-Origin: https://example-frontend.com  
Access-Control-Allow-Methods: POST  
Access-Control-Allow-Headers: Content-Type
Enter fullscreen mode Exit fullscreen mode

🔐 Why CORS Matters

Imagine you're logged into your bank in one tab. Without CORS, a malicious site in another tab could silently access your bank data just because you’re logged in.

CORS stops that. It ensures that only trusted origins can make requests to protected resources.


🔑 Important CORS Headers Explained

CORS uses several HTTP headers to control access. Here are the most important ones:

1. Access-Control-Allow-Origin

This is the most fundamental CORS header. It specifies which origins are allowed to access the resource.

Access-Control-Allow-Origin: https://myfrontend.com
Enter fullscreen mode Exit fullscreen mode

You can also use a wildcard to allow any origin (not recommended for APIs handling sensitive data):

Access-Control-Allow-Origin: *
Enter fullscreen mode Exit fullscreen mode

2. Access-Control-Allow-Methods

Specifies which HTTP methods (GET, POST, etc.) are allowed when accessing the resource:

Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Enter fullscreen mode Exit fullscreen mode

3. Access-Control-Allow-Headers

Indicates which HTTP headers can be used during the actual request:

Access-Control-Allow-Headers: Content-Type, Authorization
Enter fullscreen mode Exit fullscreen mode

4. Access-Control-Allow-Credentials

Indicates whether the browser should include credentials (like cookies or HTTP authentication) with the request:

Access-Control-Allow-Credentials: true
Enter fullscreen mode Exit fullscreen mode

5. Access-Control-Max-Age

Specifies how long (in seconds) the results of a preflight request can be cached:

Access-Control-Max-Age: 3600
Enter fullscreen mode Exit fullscreen mode

🛠️ CORS in Code (Server Examples)

📘 Using Express.js (Manual Headers)

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

app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "https://example-frontend.com");
  res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
  res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
  res.header("Access-Control-Allow-Credentials", "true");
  next();
});

app.get('/data', (req, res) => {
  res.json({ message: 'This is CORS-enabled!' });
});
Enter fullscreen mode Exit fullscreen mode

✅ Better Way: Use cors Middleware

npm install cors
Enter fullscreen mode Exit fullscreen mode
const cors = require('cors');
app.use(cors({
  origin: 'https://example-frontend.com',
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization']
}));
Enter fullscreen mode Exit fullscreen mode

⚠️ Common CORS Errors and How to Debug

1. "Access to fetch at 'X' from origin 'Y' has been blocked by CORS policy"

This is the most common CORS error and indicates that the server at URL 'X' doesn't include the proper CORS headers to allow access from origin 'Y'.

Solution: Configure the server to send the correct Access-Control-Allow-Origin header.

2. "Request header field X is not allowed by Access-Control-Allow-Headers"

This error occurs when your request includes headers that aren't explicitly allowed by the server.

Solution: Add the required headers to the Access-Control-Allow-Headers response header on the server.

3. "Method X is not allowed by Access-Control-Allow-Methods"

The HTTP method you're trying to use isn't allowed by the server's CORS policy.

Solution: Add the method to the Access-Control-Allow-Methods response header on the server.

4. "The value of the 'Access-Control-Allow-Origin' header must not be the wildcard '*' when the request's credentials mode is 'include'"

This error occurs when you're trying to send credentials (cookies, etc.) to a server that has Access-Control-Allow-Origin: *.

Solution: Specify the exact origin instead of using a wildcard, and set Access-Control-Allow-Credentials: true.


🔍 Debugging CORS Issues with Browser Dev Tools

Most modern browsers include developer tools that can help you diagnose CORS issues:

  1. Open Developer Tools: Press F12 or right-click and select "Inspect"
  2. Go to Network Tab: This shows all network requests
  3. Look for Failed Requests: CORS errors will appear in red
  4. Examine Preflight Requests: Look for OPTIONS requests to see if they're returning the correct headers
  5. Check Console: CORS errors also appear in the console with detailed messages

Example CORS Error in Console:

Access to fetch at 'https://api.example.com/data' from origin >'https://myfrontend.com' has been blocked by CORS policy: No >'Access-Control-Allow-Origin' header is present on the requested >resource.


🔒 Security Considerations

While CORS is a security mechanism, misconfigured CORS can lead to security vulnerabilities:

  • Avoid Access-Control-Allow-Origin: * for private APIs
  • 🔒 Only allow trusted origins
  • ⚙️ Be strict about allowed methods and headers
  • 🍪 Use Access-Control-Allow-Credentials: true only when necessary

Remember: CORS is a browser-enforced security feature. API endpoints can still be accessed directly using tools like curl or Postman.


🧩 Real-World Use Cases

APIs and Microservices

In modern architectures, frontend applications often need to communicate with multiple backend services hosted on different domains. CORS enables these services to securely share resources.

Third-Party Integrations

When integrating with third-party services (payment gateways, analytics, etc.), CORS allows these external services to access resources from your domain when necessary.

Content Delivery Networks (CDNs)

When your assets are hosted on CDNs with different domains, CORS allows your main website to interact with these resources.


📚 Conclusion

CORS is like a permission system for the web. It prevents unauthorized websites from messing with your data, while still letting trusted sites communicate securely.

Just remember the toy box analogy:

  • Your website is your toy box.
  • Another website’s data is your friend’s toy box.
  • The browser is your mom, who makes sure you play safely.
  • The server is your friend’s parent, who decides if you're allowed to borrow the toy.
  • CORS headers are the permission slip.

Understanding CORS is essential for modern web development, especially when working with APIs and distributed systems.


Top comments (2)

Collapse
 
almustarik profile image
Al-Mustarik

Insightful and a great article about CORS.

Collapse
 
iamismile profile image
Ismile Hossain

Thanks 😊