---
title: Same-Origin Policy
description: The Same-Origin Policy (SOP) is a browser security rule. An origin is protocol, host, and port. SOP stops a page from reading data from another origin, but still allows some cross-origin writes, embeds, and form posts.
tokens: ~565
---

# Same-Origin Policy

The Same-Origin Policy (SOP) is a browser rule that treats documents from different origins as untrusted to each other. An **origin** is the **protocol + host + port** (`https`, `app.example.com`, `443`). SOP blocks most reads of another origin's data, it does not block every cross-origin **write**. Only the browser enforces this.

## What SOP allows and blocks

A page may **not** read another origin's response body, DOM, or cookies. That is the core rule. How a request is *sent* depends on how it was made.

[CORS](/docs/web/http/cors) does not turn SOP off. It is only the server's opt-in so JavaScript may read **that HTTP response**. Another origin's DOM and cookies stay blocked.

**Forms and embeds** do not use CORS. The browser still sends them:

- Form `GET` / `POST` to another origin (the page navigates; JavaScript does not get the response as data)
- `<script>`, `<img>`, `<iframe>`, `<link>`, `<video>` from another origin
- [Cookies](/docs/web/http/cookies) on those requests, when cookie attributes allow it

That gap — a write that still happens, with no readable response — is why [CSRF](/docs/web/security/csrf) exists.

**`fetch` and XHR** do use [CORS](/docs/web/http/cors). A **simple** request (CORS-safelisted GET/HEAD/POST) is sent even when the server sends no CORS headers; JavaScript just cannot read the result. Anything else is **preflighted**: the browser sends `OPTIONS` first, and the real request goes out only if that response allows it.

## Talking across origins

These are the usual ways pages still work with another origin. They are not a single “bypass SOP” switch.

| Mechanism | Role |
| --- | --- |
| [CORS](/docs/web/http/cors) | Server opts in so JavaScript may read a cross-origin response. |
| Reverse proxy | Serve the API under the page's origin so the browser sees a same-origin request. |
| `window.postMessage` | Explicit messages between windows / iframes that agree on an origin check. |
| WebSockets | Cross-origin sockets are allowed; the browser sends `Origin` and the server may reject it. Not CORS. |
| JSONP | Old hack: a cross-origin `<script>` runs a callback. |
| `document.domain` | Legacy way to relax SOP between related subdomains. Deprecated; browsers have removed or restricted it. |