# Cross-window communication The "Same Origin" (same site) policy limits access of windows and frames to each other. The idea is that if a user has two pages open: one from `john-smith.com`, and another one is `gmail.com`, then they wouldn't want a script from `john-smith.com` to read our mail from `gmail.com`. So, the purpose of the "Same Origin" policy is to protect users from information theft. ## Same Origin [#same-origin] Two URLs are said to have the "same origin" if they have the same protocol, domain and port. These URLs all share the same origin: - `http://site.com` - `http://site.com/` - `http://site.com/my/page.html` These ones do not: - http://www.site.com (another domain: `www.` matters) - http://site.org (another domain: `.org` matters) - https://site.com (another protocol: `https`) - http://site.com:8080 (another port: `8080`) The "Same Origin" policy states that: - if we have a reference to another window, e.g. a popup created by `window.open` or a window inside ` ``` The code above shows errors for any operations except: - Getting the reference to the inner window `iframe.contentWindow` - Changing its `location`. ```smart header="`iframe.onload` vs `iframe.contentWindow.onload`" The `iframe.onload` event is actually the same as `iframe.contentWindow.onload`. It triggers when the embedded window fully loads with all resources. ...But `iframe.onload` is always available, while `iframe.contentWindow.onload` needs the same origin. ``` And now an example with the same origin. We can do anything with the embedded window: ```html run ``` ### Please wait until the iframe loads When an iframe is created, it immediately has a document. But that document is different from the one that finally loads into it! Here, look: ```html run ``` That's actually a well-known pitfall for developers. We shouldn't work with the document immediately, because that's the *wrong document*. If we set any event handlers on it, they will be ignored. ...But the `onload` event triggers when the whole iframe with all resources is loaded. What if we want to act sooner, on `DOMContentLoaded` of the embedded document? That's not possible if the iframe comes from another origin. But for the same origin we can try to catch the moment when a new document appears, and then setup necessary handlers, like this: ```html run ``` Let me know in comments if you know a better solution here. ## window.frames An alternative way to get a window object for ` ``` An iframe may have other iframes inside. The corresponding `window` objects form a hierarchy. Navigation links are: - `window.frames` -- the collection of "children" windows (for nested frames). - `window.parent` -- the reference to the "parent" (outer) window. - `window.top` -- the reference to the topmost parent window. For instance: ```js run window.frames[0].parent === window; // true ``` We can use the `top` property to check if the current document is open inside a frame or not: ```js run if (window == top) { // current window == window.top? alert('The script is in the topmost window, not in a frame'); } else { alert('The script runs in a frame!'); } ``` ## The sandbox attribute The `sandbox` attribute allows for the exclusion of certain actions inside an `