window.name 跨域隐式传递消息原理解析
发布于 作者:苏南大叔 来源:程序如此灵动~window
对象有个name
属性,这是一个非常非常奇特的属性。只要当前的这个浏览器tab
没有关闭,无论tab
内的网页如何变动,这个name
值都可以保持,并且tab
内的网页都有权限访问到这个值,这就是跨域传递消息的原理。请大家阅读本文的详细内容,来了解一下这种特异的跨域消息传递方式。
基本描述
只要两个网页在同一个浏览器的tab
里面呆过,每个网页都是可以接收和设置window.name
这个值的。前提是:这个tab
没有被关闭过。
- f5刷新多少次都可以,这是无所谓的。
- 中间跳转过多少个页面,这也是无所谓的。
- 承载过的这些页面是不是同一个域名,这都是无所谓的。
demo
原理展示,一个假设的过程
我们假设:打开一个浏览器,然后打开了淘宝网,淘宝网的网页js
代码设置了window.name
。这里的都是假设,最理想的结果。实际的情况是不一样的,马云大叔当然不会请苏南大叔吃饭的。哈哈。
window.name="马云大叔要请苏南大叔吃饭";
//window.location="https://newsn.net/";
然后没有关闭浏览器,也没有关闭tab
。在淘宝网的这个tab
的地址栏,输入了苏南大叔的博客:https://newsn.net/
。(或者前者页面主动跳转到新的域名页面,也是可以的)。这个时候,苏南大叔的博客js
代码,读取了window.name
。这个时候,就可以拿到淘宝网给苏南大叔传递的消息了。
alert(window.name);
延伸阅读iframe
跨域传递消息
基本原理中的tab
,实际上我们改成iframe
也是一样试用的。
我们可以继续假设一下,淘宝网中用iframe
嵌套了苏南大叔的博客,这个时候,苏南大叔的博客,想告诉一下淘宝网一些消息。由于跨域的原因,这个消息是无法通知的。因为top
和parent
对象,都无法获得。但是,苏南大叔的博客代码可以设置window.name
, 也就是说,iframe
这个window
的name
属性。
window.name="苏南大叔收到了马云大叔的邀请";
//window.location="https://www.taobao.com/agent.html";
设置完毕后,苏南大叔的博客newsn.net
,主动跳转自身页面到淘宝网域名下面的第一个代理页面。 这个代理页面也不做什么事情,就是读取window.name
,然后用top
或者parent
,去通知淘宝首页相关的结果即可。
top.got_msg(window.name);
上述过程仅仅发生在一个页面的iframe下面,所以,这个iframe可以是display:none
的,width:1px;height:1px
的。你懂的。
iframe
跨域消息传递在ie
下的bug
上述iframe
方案在ie
下面实际上是有个小bug
的。就是iframe
必须不能设置name=""
,否则是读取不到相关设置的。仅仅ie10系列以上浏览器上有这个问题,其他浏览器是没有这个问题的。又是万恶的ie
所独有的bug
。
这样写在ie下面是不行的:
<iframe name='xx' src='https://newsn.net/'></iframe>
需要改成这样的:
<iframe id='xx' src='https://newsn.net/'></iframe>
相关文章
- 《evercookie原理解析》 https://newsn.net/say/evercookie-start.html
思路扩展
想接收到UFO外星人给你传递的隐藏消息么?在你的页面里面读取一下window.name
吧,真的会有意外的惊喜的,不确定性就是这个游戏的乐趣所在。
事实上,在上述假设的验证过程中,苏南大叔的博客确实收到了淘宝网传递的window.name
值,淘宝网的这个值在苏南大叔用console设置后,被其他的淘宝js继续改写了。所以,看到的结果是下图类似的,这也就从侧面体现了:淘宝网确实在使用window.name
来传递特殊数据(统计)。
总结
window.name
跨域传递消息,实际上是个异类的应用,也可以说是一个小的漏洞吧。不过,这个问题存在了很多年了,估计将来也不会修复的。而且目前已经作为一项技术标准,投入到生产实践中来了。比如:跨域iframe
自适应高度。
更多跨域相关经验文章,请点击这里查看:https://newsn.net/tag/cors/ 。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。