Back to all posts

Understanding CORS

2026-07-26

CORS (Cross-Origin Resource Sharing)

CORS (Cross-Origin Resource Sharing) is a browser security mechanism that determines whether JavaScript running on one origin is allowed to access resources from another origin. It is enforced by browsers, not by servers.

Consider the following setup:

Frontend: http://localhost:5173
Backend:  http://localhost:5000

Although both are running on your machine, they have different ports, making them different origins. Because of this, the browser applies CORS rules.

What Is an Origin?

An origin is defined by three components: Protocol + Domain + Port

For example:

http://localhost:5173

Simple Requests

A simple request is one that browsers consider low risk. Typically, these are GET, POST, or HEAD requests using only a limited set of headers and content types. When a simple cross-origin request is made, the browser automatically includes an Origin header.

GET /users HTTP/1.1
Origin: http://localhost:5173

The server checks the origin and decides whether to allow it. If allowed, it responds with Access-Control-Allow-Origin header containing the client's domain (or *):

Access-Control-Allow-Origin: http://localhost:5173

The browser compares the request's Origin with the value of Access-Control-Allow-Origin.

If they match, JavaScript is allowed to access the response. If the header is missing or doesn't match, the browser blocks access to the response and throws a CORS error.

A simple cross-origin request can still be fully processed by the server. CORS only determines whether the browser exposes the response to frontend JavaScript.

What Makes a Request "Simple"?

A request is considered simple only if it satisfies all of the following conditions.

Allowed Methods

  • GET
  • POST
  • HEAD

Allowed Request Headers

Examples include:

  • Accept
  • Content-Type

Allowed Content Types

The Content-Type must be one of:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

application/json is not considered a simple content type.

Preflight Requests

When a request doesn't satisfy the conditions for a simple request, the browser first sends a preflight request using the OPTIONS method.

fetch("http://localhost:5000/login", {
  method: "POST",
  headers: {
    Authorization: "Bearer xyz",
    "Content-Type": "application/json"
  }
});

This is not a simple request because:

  • It includes an Authorization header.
  • Content-Type: application/json is not a simple content type.

Instead of sending the POST immediately, the browser first asks the server whether this request is allowed.

Step 1: Browser Sends a Preflight Request

OPTIONS /login HTTP/1.1
Origin: http://localhost:5173
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Authorization, Content-Type

This request contains:

  • the origin making the request
  • the HTTP method that will be used
  • any non-simple headers that will be included

Step 2: Server Responds

If the request is allowed, the server replies with:

HTTP/1.1 204 No Content

Access-Control-Allow-Origin: http://localhost:5173
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Authorization, Content-Type

These headers tell the browser that the actual request is permitted.

Step 3: Browser Sends the Actual Request

After receiving a successful preflight response, the browser sends the original request.

POST /login HTTP/1.1

Authorization: Bearer xyz
Content-Type: application/json

If the preflight request fails (for example, the server rejects the OPTIONS request or omits the required CORS headers), the browser never sends the actual request.

Note: CORS is enforced only by web browsers. Tools like Postman, curl, or server-to-server requests are not restricted by CORS.

Server Implementation

Most web frameworks provide CORS middleware that automatically handles CORS headers and preflight (OPTIONS) requests. Without such middleware, you'll need to return the appropriate Access-Control-Allow-* headers and handle OPTIONS requests yourself.

Note: AI was used as a writing aid; I reviewed and verified the technical content.