window.opener
属性是一个可读可写的属性,可返回对创建该窗口的 Window 对象的引用。简单点说,就是从父页面打开一个子页面,子页面是可以读取和修改父页面的信息的(注意:有一定的限制条件)。
最近测试发现大有改版,直接通过<a href='xx.html'>
打开页面无论是否设置rel ="noreferrer"
或rel ="noopener"
,得到的window.opener
属性的值都是null
。通过window.open()
打开新页面时可以获取到window.opener属性
// A.html
<script>
function test(n) {
console.log(n)
}
</script>
<body>
<button onclick="javascript:window.open('B.html')">跳到子页面</button>
</body>
B.html(子页面)
<body>
<button onclick="useOpenerMethod()">使用父页面的方法</button>
<button onclick="changeOpener()">盗换父页面</button>
</body>
<script>
function useOpenerMethod(){
window.opener.test(1234);
}
function changeOpener(){
window.opener.location.href="https://www.baidu.com"
}
</script>
在B页面(子页面)分别定义了一个调用父页面test方法的方法,还定义了一个将父页面地址改变的方法。
页面效果如下:
观察点:window.opener
从父页面A打开子页面B,在子页面的控制台中输入window,展开对象属性,并找到opener属性
可见window.opener
指向一个window对象类型,此时你再打开A页面的控制台并输入window,发现了什么?
B页面的opener指向的window对象就是A页面的window对象,接下来那就好办了。
情景测试 |
情景一 |
点击B页面的 使用父页面的方法 按钮,也就是通过window.opener.test()
调用A页面test()
方法,然后在A页的控制台可以看到:1234
情景二 |
点击B页面执行盗取父页面地址方法,A页面变成了百度首页,说明改变父页面链接成功了。
至此,说明子页面是可以调用父页面的方法的,并且可以改变父页面的链接的。实际上刚才的那些操作都是可以通过控制台输入的,也就是说我们只要在控制台就可以完成改链,调用父页面方法。
你想想看,刚刚还是在某个网站浏览,随后打开了新窗口,结果这个新窗口神不知鬼不觉地把原来的网页地址改了。这个可以用来做什么?钓鱼啊!等你回到那个钓鱼页面,已经伪装成登录页,你可能就稀里糊涂把账号密码输进去了。(目前基本不可以了,浏览器安全机制强大了,有兴趣的了解一下:站点隔离)
还有一种玩法,如果你处于登录状态,有些操作可能只是发送一个GET请求就完事了。通过修改地址,就执行了非你本意的操作
情景三 |
在B页面执行盗取父页面方法之后,父页面变成了百度首页,回到B页控制台输入window,找到opener。
发现opener 变成global类型;里面的opener也变成了null;location则报异常称不可跨域请求
情景四 |
- 通过A页面打开B页面后,将A页面关闭
- 不启动A页面,直接启动B页面
- 先启动B页面,再启动A页面
查看opener结果都如下:
opener既不是window,也不为global,直接null
解惑 |
window对象内置属性opener
只要在父页面打开子页面,不管你使用的什么跳转方式,默认都会附带上这个属性的值。
📌情景三是怎么回事呢?
现代的许多浏览器都足够安全,会检测子页面域名和父页域名是否一致,不一致,则会拒绝跨域访问,不能获取opener信息。跨域读取阻止
📌那情景四又怎么说?
先说情景四的2,3点吧,都是直接启动B页面的,并没有依赖A页面,自然opener为null
📌为什么情景三opener为global,而情景四直接为null?
情景四的第1点和情景三对比起来就更能说明问题了。情景三只是被拦截了跨域读取,但是B页面改链后"A"页面还是"活着的",只是隔断opener指向值的获取,但浏览器依然能检测到两者间"不寻常"的关系。而情景四的第1点,A页面关闭了,浏览器检测到opener指向的页面关闭了,是完全获取不到A页面的任何信息,自然是null。
子页面能调用父页面方法的前提 |
- 父子页面要在同一个域名下
不在同一域名下,浏览器安全机制阻止跨域 - 父子页面一定要分清次序,有父才有子
- 父子必须同时存在
=========================================================================================
若有不足,还望指点。
参考文档:
a标签target=‘_blank’的安全问题
site-isolation
window.opener用法