10

我最近一直在调查帧破坏代码,并且遇到了一些与我无法理解的同源策略相关的非常奇怪的行为。

假设我在域 A 上有一个页面 Breaker.html,在域 B 上有一个页面 Container.html。示例帧断路器代码将进入 Breaker.html,如下所示:

if (top !== self) top.location.href = self.location.href;

这将成功地将 Breaker.html 从 Container.html 中分离出来,但我不明白为什么会这样。根据我对同源策略的阅读,根本top.location不应该访问,因为 Container.html 与 Breaker.html 位于不同的域中。更奇怪的是,似乎 top.location只写

// Fails if Container.html is on a different domain than Breaker.html
alert(top.location);

这对我来说是有问题的,因为我正在尝试编写允许我的页面位于 iframe 中的代码,但前提是它与其父级位于同一域中(或者位于配置的允许域中)。但是,似乎无法确定这一点,因为同源政策拒绝我访问父母的位置。

所以我有两个问题,基本上:

  1. 为什么上面的帧中断代码完全起作用?

  2. 有没有办法有条件地打破框架,或者唯一能做的检查是是否top !== self?(特别是,我希望能够读取域,以便我可以提供允许域的列表;简单地检查我是否在同一个域中并不理想。)

4

3 回答 3

1

对于您对第 1 点的回答:在安全性方面,读取访问权限和写入访问权限之间存在很大差异。能够读取 top.location.href 是一个安全问题。不能写入top.location.href 。

至于您的问题的答案,我不太了解javascript,无法确定,但一个想法是假设如果读取top.location 失败(检查异常),它位于不同的域中。

于 2009-06-04T18:22:14.500 回答
0

问题 1 的答案是,由于遗留原因,可以对 top.location.href 使用相等运算符。Breaker.html 无法读取 top.location.href 但它可以将其与另一个值进行比较。

然后问题 2 的答案变为否,您必须使用 !== 来分开,因为您将无法从跨域断路器.html 对 top.location.href 执行子字符串。

我可能是错的,但这是我对当前 iframe 世界的理解。

于 2009-06-04T19:07:26.380 回答
0

这是针对问题 2:如果您想获取 parent.location 的 HREF(而不是 top.location),您可以这样做:

if ((window.top === window.parent) && (history.length==1)) parentHREF=document.referrer;

基本上这段代码的作用是:
[1]检查父框架是否是顶部框架,因为即使它不是顶部框架,您也只能获取父框架的 HREF。
[2]在加载源之前检查 iframe 的历史记录是否为空白,因为如果不是... document.referrer 将返回此帧历史记录中的最后一个 HREF。

之后,你有一个新问题:如果 history.length 的值大于 1,你可以使用主机名白名单来检查它是否必须打开:

if ([location.hostname, 'stackoverflow.com'].indexOf(location.hostname)>=0) hasToBeOpened=true;

请注意,您还有另一个选择:可以使用登录页面来检查“第一”页面是否必须打开,请使用以下代码:

<head>
<script>
var parentHREF;
if ((window.top === window.parent) && (history.length==1)) parentHREF=document.referrer;
if (/*conditions mentiones above*/) document.write("<META http-equiv='refresh' content='0;URL=http://example.com/go-here.html'>");
</script>
</head>

这样做,“第一”页将替换历史的第一个(在这种情况下是第一个)值。该代码假定“example.com”是您的域。

于 2014-09-29T01:16:30.717 回答