Unsafe JavaScript尝试访问具有URL的框架

113
当我试图将哈希值设置为包含另一个域名 URL 的 iframe 的父级 URL 时,出现以下错误:

Unsafe JavaScript attempt to access frame with URL "URL1" from frame with URL "URL2". Domains, protocols and ports must match.

如何解决这个问题?

3
请添加更多细节、代码片段、错误信息和你所使用的框架。越详细越好。 - fifigyuri
5
如果您在网站中嵌入了加载框架的g+1、Facebook点赞或分享以及Twitter社交插件,但出现了相同的错误,应该怎么办?请问需要进行哪些处理? - user1115361
问题是为什么Facebook和Google的脚本会试图访问我的网站元素。 - sergio
6个回答

125

如果你在一个不同域的子文档中访问顶级窗口的location.hash属性是不允许的,但是你可以设置location属性本身。

这意味着,假设顶级窗口的位置是http://example.com/page/,那么不要使用以下方式:

parent.location.hash = "#foobar";

你需要知道父元素的位置并执行相应操作。

parent.location = "http://example.com/page/#foobar";

由于资源没有被导航,因此这将按预期工作,仅更改URL的哈希部分。

如果您要将其用于跨域通信,则建议改用easyXDM


13
目前还没有人将这个回答标记为答案,但它已经获得了60个赞。应该有一个徽章来表彰这种情况。 - zachzurn
36
这个徽章应该叫什么?“回复了懒人” - nzifnab
1
嘿@atul,请友善地将此答案标记为最佳答案。尊重约定,让我们所有人都能从他人的知识中受益... - Clint Eastwood

14

当两个框架具有不同的域时,无法进行跨框架脚本编制 -> 安全性。

请参见:http://javascript.about.com/od/reference/a/frame3.htm

现在来回答你的问题:没有解决方案或变通方法,你只需检查你的网站设计,为什么必须有两个来自不同域的框架改变另一个的url。


83
这是一个常见的需求,当你想将第三方应用程序嵌入到你的网站中时,尤其是在Web服务等不可用的情况下。 - Jacques

10

当我尝试更改iframe.src的域时,也会收到相同的错误消息。

对我来说,答案是将iframe.src更改为同一域上的URL,但实际上是一个HTML重定向页面到所需域。然后,在我的iframe中显示了另一个域,没有任何错误。

像魔法般奏效:)


你能详细说明一下你在这里具体做了什么吗? - Devin Rhode
如果您能简要解释一下,那将非常有帮助。 - Madhusudhan
2
最新版的Chrome无法正常工作:它不会检查src参数,而是加载实际的URL。因此,重定向技巧不幸地无法帮助任何方式 :-( - lucaferrario
3
我认为Tommy所提到的是服务器端代理。请参考以下链接http://benalman.com/projects/php-simple-proxy/,http://developer.yahoo.com/javascript/howto-proxy.html或https://www.google.com/webhp?q=server%20side%20proxy%20in%20%7Byour%20favorite%20language%7D或René de Kat的解决方案https://dev59.com/5m855IYBdhLWcg3weEKJ#11224975。 - Oskar Austegard
很不错。但它只是说明了绕过这个问题通常是微不足道的。好吧,假设我是一个邪恶的恶意黑客,我想运行跨域脚本攻击。很有可能我会知道这些工具,并使用它们。就浏览器安全修复而言,这与IE不允许您在没有警告的情况下在本地运行Javascript一样愚蠢。解决不了任何问题,反而创造了一堆新问题。 - Yitzhak

7
一个解决方案是使用一个本地文件来获取远程内容。
远程包含.php
<?php
$url = $_GET['url'];
$contents = file_get_contents($url);
echo $contents;

The HTML

<iframe frameborder="1" id="frametest" src="/remoteInclude.php?url=REMOTE_URL_HERE"></iframe>
<script>
    $("#frametest").load(function (){       
    var contents =$("#frametest").contents();
});


1
这为跨站脚本漏洞打开了大门。一个可能攻击的例子:
  1. 我在myevilserver.com上创建一个页面,看起来就像你的网站一样,包括一个登录表单,POST回到myevilserver.com
  2. 我向你的用户发送一封假电子通讯,其中包含指向https:// yoursite.com/remoteInclude.php?url=myevilserver.com的链接
  3. 他们在你的网站上看到一个我捕获在我的服务器上的登录表单。
- EricP
2
一个可能的解决方案是让remoteInclude.php检查所有的URL是否在预先批准的域名列表中。 - EricP
这并不能解决跨站脚本漏洞问题。我无法通过Javascript对外部网站做任何事情,而这些都可以从服务器端完成。所有这样做的结果只是阻碍了浏览器本身,并通过引入额外的步骤使Web应用程序变得不那么有用。如果您通过ajax加载、重写链接和提交回来仍然可以完成所有这些操作。如果这些方法都不起作用,那么可以通过php或其他语言进行远程rpc调用。对于普通编码人员来说,这甚至是一个荒谬的问题。 - Yitzhak

3

我发现使用 Facebook 的 XFBML 版本的“赞”按钮而不是 HTML5 版本可以解决这个问题。在您想要出现按钮的位置添加以下代码:

<div id="fb-root"></div>
<script>(function (d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s); js.id = id;
    js.src = "//connect.facebook.net/en_GB/all.js#xfbml=1";
    fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>

<fb:like send="true" layout="button_count" width="50" show_faces="false" font="arial"></fb:like>

然后将以下代码添加到你的HTML标签中:
 xmlns:fb="http://ogp.me/ns/fb#"

2
Facebook与这个问题有什么关系? - Andrew Camilleri 'Kukks'
17
因为你在 Facebook 的“赞”按钮上也遇到了这个错误,而且当你搜索答案时找到了这个页面,所以认为其他人可能也需要这个答案。 - Luke Alderton

1
问题在于,即使您创建代理或加载内容并将其注入为本地内容,任何该内容定义的脚本都将从其他域加载并导致跨域问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接