ReviseAlgo Logo

Security

CORS — Cross-Origin Resource Sharing

Master Cross-Origin Resource Sharing (CORS) in JavaScript. Learn the Same-Origin Policy, preflight OPTIONS requests, and configure CORS headers safely.

Last Updated: July 15, 2026 10 min read

1. Introduction

Cross-Origin Resource Sharing (CORS) is a browser security mechanism that allows servers to specify which origins are permitted to read resources from their system, relaxing the browser's default Same-Origin Policy (SOP).

2. Why It Matters

By default, the Same-Origin Policy prevents client-side scripts on siteA.com from reading API responses from siteB.com. CORS provides a secure handshake protocol using HTTP headers, allowing servers to grant cross-origin read permissions to specific, trusted domains.

3. Real-World Analogy

Think of a Consular Passport Control Checkpoint:

  • Same-Origin Policy (Sovereign border lock): A country locks its borders, allowing only its own citizens (scripts from the same origin) to trade goods.
  • CORS Handshake (Visa checkpoint): A foreigner (cross-origin script) arrives at the gate. The border guard checks the consulate entry list: "Is this foreign origin allowed to trade?" (checks Access-Control-Allow-Origin). If the origin matches the whitelist, the foreigner enters. If they represent a blocklisted origin, they are turned away.
  • Preflight OPTIONS (Courier verification): Before sending a cargo truck (a state-changing PUT/DELETE request), the foreign company sends a courier (an OPTIONS request) to ask the guard: "If we send a truck tomorrow carrying these items (headers), will you let it pass?" The guard approves or rejects the preflight request before the cargo truck is dispatched.

4. The CORS Handshake & Headers

When a cross-origin request is made, the browser automatically attaches the Origin header. The server must respond with the appropriate CORS headers to authorize access:
Access-Control-Allow-Origin: Specifies which origins can read the response (e.g. https://trustedpartner.com or * for public APIs).
Access-Control-Allow-Methods: Lists the HTTP methods allowed for cross-origin requests.
Access-Control-Allow-Headers: Lists the custom HTTP headers allowed in requests.

5. Preflight (OPTIONS) Requests

For requests that could affect server state (such as POST requests with JSON payloads, or PUT/DELETE requests), the browser sends a preflight OPTIONS request first. This request checks if the server supports cross-origin requests before dispatching the actual request:

6. Practical Example

This Express backend configuration implements CORS security by restricting access to a specific, whitelisted domain:

7. Common Mistakes

  • Setting Access-Control-Allow-Origin to "" when using credentials: If your API requests require cookies or authorization headers, you must set Access-Control-Allow-Credentials to true. When credentials are enabled, the wildcard origin * is blocked. You must return the explicit origin (read from the request's Origin header) instead.

8. Quick Quiz

Q1: Which HTTP request method is used by browsers to perform preflight checks before sending cross-origin POST or PUT requests?

A) POST

B) OPTIONS

Answer: B — The browser sends a preflight OPTIONS request to verify that the server supports cross-origin requests before dispatching the actual request.

9. Scenario-Based Challenge

The Multi-Origin API Gateway Configuration:

An API server needs to support cross-origin requests from two client domains: https://app1.site.com and https://app2.site.com. Design an Express middleware wrapper that reads the Origin header and sets Access-Control-Allow-Origin dynamically if the requesting origin is in the whitelist.

10. Debugging Exercise

Explain why this backend API fails to authorize cross-origin requests from the client, and how to fix it:

// Express Endpoint
app.post('/api/save', (req, res) => {
  // Bug: setting Access-Control headers inside the route, but not handling OPTIONS preflight!
  res.setHeader('Access-Control-Allow-Origin', 'https://myclient.com');
  res.setHeader('Access-Control-Allow-Methods', 'POST');
  res.json({ saved: true });
});

// Client console output: // Access to fetch at '/api/save' from origin 'https://myclient.com' has been blocked by CORS policy: // Response to preflight request doesn't pass access control check! Why?

View Solution

Diagnosis: The browser sends a preflight OPTIONS request before executing the POST request. Because the route handler is only registered for the POST method, the preflight OPTIONS request is ignored or rejected by the server, causing the CORS check to fail.

Fix: Handle OPTIONS requests or register CORS headers as global middleware that intercept all request methods (including OPTIONS):

// Enable CORS middleware globally for all routes and preflight checks
import cors from 'cors';
app.use(cors({ origin: 'https://myclient.com' }));

11. Interview Questions

🟢 Q1: What is the Same-Origin Policy (SOP) and how does CORS relate to it?

Answer: The Same-Origin Policy (SOP) is a core browser security mechanism. It prevents scripts on one website from reading or modifying data on a different origin (defined by scheme, host, and port).
CORS (Cross-Origin Resource Sharing) is a secure handshake protocol that relaxes the Same-Origin Policy. It allows servers to use HTTP response headers (like Access-Control-Allow-Origin) to grant cross-origin access permissions to trusted client domains.

12. Production Considerations

  • Never use Wildcard in Production: Avoid setting Access-Control-Allow-Origin: for private APIs in production. Always validate and restrict access to trusted origins to protect user data from unauthorized cross-origin requests.