使用 window.name 跨域——应该使用双 onload 吗?

Posted

技术标签:

【中文标题】使用 window.name 跨域——应该使用双 onload 吗?【英文标题】:Cross domain using window.name -- double onload should be used? 【发布时间】:2013-10-29 13:03:46 【问题描述】:

我正在努力弄清楚为什么我的代码以特定方式(而不是其他方式)工作:

+----------------------------+
| jsfiddle                   |
|                            |
|              +---------+   |
|              |         |   |
|              |  jsbin  |   |
|              +---------+   |    
+----------------------------+

目标:

jsfiddle 应该连接到 jsbinjsbin 应该返回数据到 jsfiddle 使用 window.name(跨域技术)。

(再次——代码正在运行)

jsbin's 响应是一个 html 页面,带有:

  <script>
      window.name = 1*(new Date());
  </script>

这是jsFiddle的代码:

/*1*/   var f;
/*2*/   
/*3*/   function loadRequest()
/*4*/   
/*5*/       f.onload = function ()
/*6*/       
/*7*/           alert(f.contentWindow.name);
/*8*/           frame.parentNode.removeChild(frame);
/*9*/       
/*10*/       f.src = 'about:blank';
/*11*/   
/*12*/   
/*13*/   $(".b").on('click', function ()
/*14*/   
/*15*/       f = document.createElement('iframe');
/*16*/       f.name = framename = 'fetchData';
/*17*/       f.onload = loadRequest;
/*18*/       f.src = 'http://jsbin.com/AjUyoYU/8/quiet';
/*19*/       document.body.appendChild(f);
/*20*/   );

如您所见 - 代码有效:http://jsfiddle.net/7Nawt/2/

那么问题在哪里呢?

查看第 17 行,我确实iframe 附加了一个 onload 处理程序。 (loadRequest)。

但是 loadRequest 方法 - 反过来 --attachs again(!! --line #5) 一个 onload 函数。

我不明白为什么它这样工作。

我的意思是:常识告诉我loadRequest 方法应该是:

function loadRequest()
     
             alert(f.contentWindow.name);
             frame.parentNode.removeChild(frame);
    

但它不起作用。

我错过了什么? (任何其他尝试显示:跨域错误)

【问题讨论】:

【参考方案1】:

在检查window.name之前,您需要将iframe窗口发送回父窗口可以访问的域,否则会出现跨域错误。所以,加载完远程页面设置window.name后,发送到不受同源策略约束的about:blank,然后从父窗口读取window.name

这里的第一个技巧是window.name 无论您将窗口发送到哪里都会一直存在。因此,您将窗口发送到远程域,让它设置window.name,将其发送回可访问的域,然后读取它。

第二个技巧是about:blankAB 来说都是一个快乐的环境。等等 - 没有跨域错误。

【讨论】:

非常感谢我的朋友。 另一种解决方案是 iframe 内的窗口在设置名称后会更改其位置 - 但随后我将不得不等待两次页面加载。 (为了读名字) 这可行。不过,我认为从外部页面执行此操作是安全的。在脚本运行并且页面的其余部分加载之前,不应触发 onload。此外,关于您的第二个技巧编辑,更多的是为 A 提供一个快乐的环境; B 应该没关系。如果需要,您可以将其发送回域 A 而不是 about:blank。

以上是关于使用 window.name 跨域——应该使用双 onload 吗?的主要内容,如果未能解决你的问题,请参考以下文章

框架元素-跨域访问-window.name

window.name跨域

跨域问题实践总结!下(JSONP/document.domain/window.name)

window.name跨域

跨域 window.name

跨域问题实践总结! 上(JSONP/document.domain/window.name)