Why Does Your Browser Block Cross‑Origin Requests? Understanding Same‑Origin Policy and CORS

This article explains the browser's same‑origin policy, why it exists to prevent attacks such as XSS and CSRF, how origins are defined by protocol, host and port, and how CORS, simple requests, and preflight requests enable controlled cross‑origin communication.

Architect's Tech Stack
Architect's Tech Stack
Architect's Tech Stack
Why Does Your Browser Block Cross‑Origin Requests? Understanding Same‑Origin Policy and CORS

Introduction

In a recent front‑end interview, a high‑frequency question about POST requests led to a deep dive into same‑origin policy and cross‑origin resource sharing.

Same‑Origin Policy

The same‑origin policy (SOP) restricts how a document or script from one origin can interact with resources from another origin, protecting users from security threats such as XSS, SQL injection, OS command injection, HTTP header injection, CSRF, and others.

What Is an Origin?

An origin consists of three components: protocol (e.g., http or https), host (the domain name or IP address), and port. Two URLs are considered same‑origin only when all three match.

Examples: http://test.home.com:8080/dir/page.html – Same origin (only path differs) https://test.home.com:8080/secure.html – Different origin (protocol differs) http://test.home.com:8081/dir/etc.html – Different origin (port differs) http://online.home.com:8080/dir/other.html – Different origin (host differs)

Impact of SOP

SOP manifests in three areas:

DOM access restriction: Scripts cannot read or manipulate the DOM of pages from other origins.

Web data restriction: XMLHttpRequest or Fetch can only target resources sharing the same origin, mitigating CSRF attacks.

Network communication restriction: Browsers block cross‑origin network responses unless explicitly allowed.

CORS (Cross‑Origin Resource Sharing)

CORS provides a controlled way for browsers to relax SOP. The server includes specific HTTP headers indicating which origins are permitted. The browser first sends a preflight OPTIONS request for non‑simple requests to verify permission.

Simple Requests

A request is considered simple when it meets all of the following conditions:

Uses only the GET, HEAD, or POST method.

Contains only safe request headers such as Accept, Accept-Language, Content-Language, Last-Event-ID, and Content-Type limited to application/x-www-form-urlencoded, multipart/form-data, or text/plain.

Does not use a custom ReadableStream object.

Does not include user‑defined headers.

No event listeners are registered on XMLHttpRequestUpload.

Preflight Requests

For non‑simple requests, the browser automatically sends a preflight request containing special headers: Access-Control-Request-Method – the HTTP method to be used (e.g., POST). Access-Control-Request-Headers – a comma‑separated list of additional headers the actual request will send. Access-Control-Allow-Origin – indicates which origin may access the resource (cannot be a wildcard when credentials are included). Access-Control-Max-Age – optional cache duration for the preflight response.

If the server approves the preflight request, subsequent actual requests include an Origin header and the server responds with Access-Control-Allow-Origin.

Credentials and Wildcards

When a request includes credentials (e.g., cookies), the server must specify an explicit origin in Access-Control-Allow-Origin rather than *, otherwise the request fails. Similarly, Access-Control-Allow-Headers and Access-Control-Allow-Methods should list allowed values instead of using a wildcard to avoid security risks.

Full Request Flow

Conclusion

A preflight request is an automatic OPTIONS request sent by the browser during CORS to ensure security and let the server decide whether to allow the actual cross‑origin request.

Cross‑origin requests are blocked by default due to SOP. When a web page needs to access resources on a different origin, the browser performs a preflight request that includes headers like Origin and Access-Control-Request-Method. The server validates these headers and, if permitted, returns Access-Control-Allow-Origin and related headers, after which the browser proceeds with the actual request. This mechanism protects user data and privacy while enabling legitimate cross‑origin interactions.

CORSBrowserweb securitypreflightsame-origin
Architect's Tech Stack
Written by

Architect's Tech Stack

Java backend, microservices, distributed systems, containerized programming, and more.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.