Mastering Same-Origin Policy and CORS: A Complete Guide for Secure Web Development
This article explains the fundamentals of the same‑origin policy, its impact on DOM, web data and network requests, and provides a detailed overview of CORS, simple requests, preflight requests, and the necessary response headers to securely enable cross‑origin communication in modern browsers.
Preface
During a recent interview at ByteDance, the candidate was asked a high‑frequency front‑end question about POST requests, which led to a deep dive into same‑origin policy and CORS.
Same‑Origin Policy
The same‑origin policy restricts how a document or script loaded from one origin can interact with resources from another origin. Two URLs are considered same‑origin only when their protocol, host, and port are identical.
Protocol : defines the rules for data exchange, e.g., HTTP or HTTPS.
Host : the computer or device connected to a network that provides resources or services.
Port : the communication endpoint between processes on a host.
The policy manifests in three areas:
DOM access restriction : scripts cannot directly access the DOM of a page from a different origin, preventing data theft.
Web data restriction : XMLHttpRequest or Fetch can only request resources from the same origin, mitigating CSRF attacks.
Network communication restriction : browsers block responses from cross‑origin requests unless explicitly allowed.
Browsers therefore limit cross‑origin HTTP requests from scripts unless the server provides appropriate CORS headers.
CORS (Cross‑Origin Resource Sharing)
CORS is a mechanism that allows controlled cross‑origin requests. The server indicates permitted origins via response headers, and browsers perform a preflight OPTIONS request for non‑simple requests.
Simple Requests
A request is considered simple and does not trigger a preflight when it meets all of the following conditions:
Uses only GET, HEAD, or POST methods.
Contains only standard 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 ReadableStream object.
Does not include custom request headers.
No event listeners are registered on XMLHttpRequestUpload.
Preflight Request
For non‑simple requests, the browser first sends an OPTIONS request (preflight) to determine whether the actual request is safe. The preflight includes special headers:
Access-Control-Request-Method: the HTTP method that will be used (e.g., POST).
Access-Control-Request-Headers: a comma‑separated list of additional headers the actual request will send.
The server responds with headers such as
Access-Control-Allow-Origin,
Access-Control-Allow-Methods, and
Access-Control-Allow-Headers. When credentials (e.g., cookies) are involved, the server must not use a wildcard (*) for
Access-Control-Allow-Origin; it must specify the exact allowed origin.
Credentials and Wildcards
To protect user data, servers should avoid using
*for
Access-Control-Allow-Origin,
Access-Control-Allow-Headers, and
Access-Control-Allow-Methods. Instead, they should list specific origins, headers, and methods that are permitted.
Complete Request Flow Diagram
Summary
The preflight request is an automatic OPTIONS request sent by the browser during CORS to ensure security before the actual cross‑origin request is made. It allows the server to decide whether to permit the request based on origin, method, and headers.
Cross‑origin requests are blocked by default due to the same‑origin policy. When a web page needs to access resources from another origin, the browser sends a preflight request to verify server permissions, and only proceeds if the server responds with appropriate
Access-Control-Allow-*headers.
Using the preflight mechanism effectively mitigates security risks associated with cross‑origin requests, protecting user data and privacy.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.