2012-01-31 108 views
5

我知道跨浏览器域调用的解决方案。使用JSONP,进行代理调用,或接受服务器上的域。今天在我的公司发现了更多奇怪的方式。iframes跨域问题

方法:

他们正在改变主机通过使用第二服务器的主机匹配这个 -

window.location.host = "xyz.com"; 
      or 
document.domain = "xyz.com"; 

然后,他们正在创建一个隐藏的iframe和iframe中获取内容并更换内容可见元件。

问题:

它的工作原理是iframe,但如果我这样做Ajax调用,这是行不通的。对此有何话语?

+0

这听起来像一个错误或漏洞。你测试过哪些浏览器? – Halcyon 2012-01-31 20:23:04

+0

它适用于IE,Chrome。我没有在Firefox中测试 – emphaticsunshine 2012-01-31 20:24:57

+3

我不确定'window.location.host',但更改'document.domain'确实允许同一父域中的两个不同的子域进行通信。 https://developer.mozilla.org/zh/Same_origin_policy_for_JavaScript – djd 2012-02-08 02:07:51

回答

3

我不是JSONP的粉丝,它创建的数据和表现之间的耦合,所以我之前研究这个问题,那么,有一个技巧,你可以使用,按照这个:

假设我们有主窗口命名为A和B.命名 A和B必须来自同一个主机提供的iframe的“孩子”窗口,但可以有不同的子域,是这样的:

A从SUB1服务.example.com

B由sub2.example.com提供

浏览器让你修改文档的领域,但仍然限制你在那,所以你只能通过直至到达主机中移除子域更改域,并因此在您更改域名,如所以:

document.domain = "example.com"; 

B中你第一次做一个AJAX调用其领域(sub2.example.com),然后将第一个请求发送后您更改域名就像一个,因此这两个文档有相同的域。 由于您向B中的原始域发出了请求,因此浏览器将允许您继续向其发送请求,但由于您也更改了域,现在A和B具有相同的域,因此它们可以相互通信。

在更改域之前,首先在B中将至少一个请求发送到其原始域是很重要的。 同样,如果两个页面不是从同一个主机提供的,它不会工作,所以在大多数情况下它不能解决问题,但它确实让您有更多的操作空间。

我不止一次使用过这个技巧,并且没有遇到任何问题,据我所知,它在所有浏览器中都可以使用,如果在某些情况下它不适用,请告诉我。

这里有一个伪例如:

in A 
================== 
document.domain = "example.com"; 
var child; // keep reference to B 
function setChild(win) { 
    childDocument = win; 
} 

function handleMessage(message) { 
    do what ever it is you need to 
} 

in B 
================== 
make ajax request 
document.domain = "example.com"; 
parent.setChild(this); 

function ajaxCallback(message) { 
    parent.handleMessage(message); 
} 
+0

我也会尝试。但我只是通过更改域来尝试Ajax,并且它在早些时候并不适用于我。但我会试试这种方式。 Iframe工作正常的情况下子域调用。你可以在这里找到解决方案:https://github.com/emphaticsunshine/Cross-sub-domain-solution – emphaticsunshine 2012-02-13 20:05:05

+0

你必须先做一个ajax调用,然后才能更改域名,否则,因为在更改域名之前ajax请求,由于安全策略,请求将失败。如果我理解你的解决方案,那么它就像jsonp一样,限制iframe源只能从同一主机提供。 – 2012-02-13 23:52:47