I just learned about the rel="noopener" attribute, which makes the opened windows unaware of their opener. I played with it a bit and got window.opener === null all the time, until I found out that it's now the new default in all modern browsers.
Now, I'd like to actually read the window.opener property to see how it works:
<!-- http://opener-from.test/ -->
<a href="http://opener-to.test/" target="_blank">no rel</a>
<a href="http://opener-to.test/" target="_blank" rel="opener">rel="opener"</a>
<a href="http://opener-to.test/" target="_blank" rel="noopener">rel="noopener"</a>
<!-- http://opener-to.test/ -->
<script>
console.log(window.opener);
</script>
The no rel and rel="noopener" links just make the destination get window.opener === null. As for the rel="opener", it works great it Firefox and Safari, but in Google Chrome I'm getting the error:
Uncaught DOMException: Blocked a frame with origin "http://opener-to.test" from accessing a cross-origin frame.
I tested it in Chrome 91. How can I access the window.opener in the context of target="_blank" in Google Chrome?
This has nothing to do with the default of
rel, it has to do with cross-origin access. From MDN's documentation foropener:(my emphasis)
console.log(window.opener)will try to access properties onwindow.opener.Having
rel="opener"makes it possible to do navigation in the opener, but not to access global variables (including functions) exposed by that window. It also makes it possible to usepostMessageto talk to the opener window.If you just want to see whether you have access to opener, do
console.log(window.opener === null)instead and see whether it'strue(you don't have access) orfalse(you do have limited access).Even with
rel="opener", though, it's limited access as indicated by the MDN quote above. You cannot get full access towindow.openercross-origin (only same origin).This ability to allow only limited access to the object's contents isn't just magic that browsers can do, you can do it in JavaScript itself via
Proxy:Regarding why Chrome gives you the error but non-Chromium browsers like Firefox don't: Different consoles are implemented differently. Apparently Firefox's console is written to show you what it's allowed to show you, but Chrome's just applies its usual object handling and triggers the access error.