6 votesby stackoverflow.com/users/3191written 2021-05-07
Consider the following code:
const iframe = document.appendChild(document.createElement("iframe"));
iframe.src = "/a";
iframe.onload = () => {
const windowA = iframe.contentWindow;
iframe.src = "/b";
iframe.onload = () => {
const windowB = iframe.contentWindow;
console.log("window before navigation === window after navigation?", windowA === windowB);
};
};
It turns out that this logs true. And, a lot of websites depend on this being true: they grab a reference to iframe.contentWindow, or perhaps window.frames[0], before navigation. And then they keep using it after navigation.
(Note that in our example, we initiated the navigation, by doing iframe.src = "/b". So in theory we could have known at that time to grab a new reference to iframe.contentWindow. But in the general case, the navigation could happen without the outer frame being involved, e.g. the user could click a link in the iframe, or code inside the iframe could do location.href = "/c".)
How can this be true? After all, we navigated to an entirely different page---it's going to have a new Window (with a fresh global scope, not polluted by any globals declared by the previous page), a new Document, etc. etc.
It's true because of WindowProxy. iframe.contentWindow, or window.frames[0], or any other way of attempting to access a window, return a WindowProxy object, not a Window object. That WindowProxy object delegates to whatever the current Window is. In our example, it delegates to the Window for /a before navigation, and the Window for /b after the navigation.