html5 javascript-如何捕获尝试从沙盒iframe启动导航?

问题描述 投票:9回答:3

我有一个沙盒iframe,不允许更改位置:

<iframe sandbox="allow-forms allow-popups allow-pointer-lock allow-same-origin allow-scripts" class="iframe visible" src="thesource.html" width="100%" scrolling="auto" frameborder="0"></iframe>

如果iframe尝试取消框架本身或更改位置,我会看到一个空白页面,因为浏览器会停止iframe的操作。这是来自Chrome的日志:

不安全的JavaScript尝试使用URL“http://example.com”从具有URL“http://otherdomaian.com”的帧开始导航。尝试导航顶层窗口的框架是沙箱,但未设置“允许顶部导航”标记。

这很好,但我想抓住这个,所以如果它发生我将转移到下一个iframe。那我怎么抓住这个尝试呢?

编辑:

我添加了一个jsfiddle code(检查控制台日志中的错误)

我也试着听一个没有成功的事件:

document.addEventListener('error', receiveMessage, true);
function receiveMessage(error) {
    alert("iframe tried to unframe itself");
}
javascript html html5 iframe sandbox
3个回答
10
投票

我是新来的,所以我没有足够的声誉来评论答案,如果我做错了,我道歉,但遗憾的是,接受的解决方案无法实现您的目标。

我已经能够证明我的意思是,一旦DOM准备就绪,就可以通过上面的JSFiddle运行脚本(控制台中没有警报但仍然有错误)。这里有一些关于当前小提琴发生的事情的更多细节:

// running with the No wrap - in <head> option
var frame = document.querySelector('iframe'); // null, the iframe isn't there yet
try {
    frame.src="http://wedesignthemes.com/themes/redirect.php?theme=wedding";
} catch(e) {
    // TypeError here, no hints about the iframe :(
    alert('Error!');
}

被捕获的异常与iframe无关,实际上是尝试在src值上设置null属性时的类型错误。

您真正想要做的是捕获iframe内部的错误(当沙盒脚本尝试访问window.top时),但由于Same-origin policy,这是不可能的。顺便说一句,设置"allow-same-origin"沙箱标志只有当iframe内容从与顶级文档相同的origin提供时才有效。例如。一旦iframe的srclocation改为另一个originthere's no way to touch anything inside

有很多方法可以跨越iframe边界进行交流,例如使用window.postMessage或使用iframe的location.hash的旧的和更黑客的方式,但我假设你不能影响进入你的iframe的页面的来源。 (一个好的开发人员当然可以接受建议并看到这样的功能可能很有用。)

我能够在不违反任何浏览器安全策略的情况下捕获此错误的唯一方法是设置allow-top-navigation沙箱标志,然后使用顶级文档中的window.onbeforeunload处理程序来捕获来自子iframe的导航尝试。我永远不会推荐这个,因为用户体验很糟糕。在没有提示用户是否要离开页面的情况下,无法阻止导航。以下概念证明:

<iframe id="myframe" sandbox="allow-scripts allow-top-navigation"></iframe>
<script>
  var url = "http://wedesignthemes.com/themes/redirect.php?theme=wedding",
      frame = document.getElementById("myframe"),
      listener;
  listener = window.addEventListener("beforeunload", function(e) {
      e.preventDefault();
      e.stopImmediatePropagation();
      // The iframe tried to bust out!
      window.removeEventListener("beforeunload", listener);
      return "This is unavoidable, you cannot shortcut a " +
             "navigation attempt without prompting the user";
  });
  frame.src = url;
</script>

所以很遗憾,如果没有第三方内容开发人员的帮助,我无法在当前的浏览器实现中找到任何方法。我在HTML5规范中读到了一些有趣的东西,可能会让我们在将来做这样的事情(不幸的是,我可以在这里插入我的链接数量),所以我会随着事情的进展留意。


1
投票

例:

有额外限制:

<iframe src="demo_iframe_sandbox.htm" sandbox=""></iframe>

Internet Explorer 10,Firefox,Chrome和Safari支持sandbox属性。

注意:Internet Explorer 9及更早版本或Opera中不支持沙箱属性。

定义和用法

如果指定为空字符串(sandbox =“”),则沙箱属性会为内联框架中的内容启用一组额外限制。

sandbox属性的值可以是空字符串(应用所有限制),也可以是以空格分隔的预定义值列表,这些值将删除特定限制。

HTML 4.01和HTML5之间的差异

沙箱属性是HTML5中的新属性。

句法

<iframe sandbox="value">

属性值

  1. “”=>适用以下所有限制
  2. allow-same-origin =>允许将iframe内容视为与包含文档的原点相同
  3. allow-top-navigation =>允许iframe内容从包含文档中导航(加载)内容
  4. allow-forms =>允许表单提交
  5. allow-scripts =>允许脚本执行

javascript:是一种奇怪的URI协议。它适用于某些上下文,但不是全部 - 例如,窗口的位置不能设置为这样的URI。 (虽然您可以将一个javascript:URI指定给window.location,作为运行脚本的一种非常迂回的方式,但窗口的位置不会保持设置为该值。)

要将内容写入IFRAME,请获取对该框架文档的引用并写入该文档。这样做将要求您设置allow-same-origin沙箱标志。

<iframe id="myframe" sandbox="allow-scripts allow-same-origin" src="about:blank"></iframe>

<script>
    var frame = document.getElementById("myframe");
    var fdoc = frame.contentDocument;

    fdoc.write("Hello world"); // or whatever
</script>

实例:http://jsfiddle.net/wUvrF/1/


0
投票

你现在可以用allow-top-navigation-by-user-activation做到这一点

© www.soinside.com 2019 - 2024. All rights reserved.