What is window.origin
? It doesn't seem to be documented in the usual place.
It looks like it might be very similar to window.location.origin
- for example, here on Stack Overflow, both return
https://stackoverflow.com
But inside an iframe
, they're different:
console.log(window.location.origin);
console.log(window.origin);
https://stacksnippets.net null
The embedded snippet is inside an iframe
without allow-same-origin
. If you change the iframe, for example, if you edit Stack Overflow's HTML and manually add the attribute:
<iframe name="313b857b-943a-7ffd-4663-3d9060cf4cb6" sandbox="allow-same-origin allow-forms allow-modals allow-scripts" class="snippet-box-edit" frameborder="0" style="">
^^^^^^^^^^^^^^^^^^
and then run the snippet, you get:
https://stacksnippets.net https://stacksnippets.net
The same sort of behavior is exhibited on other sites with <iframe>
s.
Google does not appear to have any authoritative links on the subject. Searching for the exact phrase + Javascript gives many results related to iframe
s and postMessage
, but no precise description of what window.origin
actually is.
Calling postMessage
from a child iframe
appears to result in the parent window receiving a message with the origin
property matching the window.origin
of the child frame - without allow-same-origin
, it's null
, otherwise it looks like it's the same as the window.location.origin
of the child.
The above is what I think I've figured out from guessing-and-checking, but I'm nowhere near certain. I'd appreciate a confirmation/explanation, preferably with a link to an authoritative source.
WindowOrWorkerGlobal.origin returns the origin of the environment, Location.origin returns the origin of the URL of the environment.
Unfortunately Stack-Snippets null-origined frames will make for a confusing example...
At the risk of paraphrasing the specs themselves, let's say we are on https://example.com
and from there, we create a new <iframe> element without an src
attribute:
var frame = document.createElement("iframe")
frame.onload = function() {
var frameWin = frame.contentWindow;
console.log(frameWin.location.href); // "about:blank"
console.log(frameWin.location.origin) // "null"
console.log(frameWin.origin) // "https://example.com"
}
document.body.appendChild(frame);
The location
of our frameWin
is "about:blank"
and its location.origin
is "null"
, because "about:blank"
is an opaque origin.
However, the frame's Window frameWin
got its own origin
set to the one of the parent Window ("https://example.com"
) which was set when frameWin
's browsing context got initialized.
If you wish a little diving into the specs here are the relevant steps for the previous example:
frame
creation:
https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-iframe-element:about:blankIf the element has no
src
attribute specified, or its value is the empty string, leturl
be the URL "about:blank".
frame
https://html.spec.whatwg.org/multipage/browsers.html#creating-browsing-contexts:about:blankIf invocationOrigin is not null, and url is about:blank, then return invocationOrigin.
So here it has been determined that origin
of the new browsing context is invocationOrigin
, i.e the origin
of the browsing context that did create frame
, while url
, used by location
, is "about:blank"
.
Now the case of StackSnippets sandboxed frames is a bit particular in that they do have an src
and thus a tuple-origin url, but since their sandbox
attribute makes their origin opaque, they'll behave at the inverse of what is exposed in the previous example, making self.origin
return "null"
and location
return the iframe's src
's URL.