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

Tom*_*Tom 11 html javascript iframe html5 sandbox

我有一个沙盒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>
Run Code Online (Sandbox Code Playgroud)

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

不安全的JavaScript尝试从URL为" http://otherdomaian.com "的框架启动URL为" http://example.com "的框架导航.尝试导航顶层窗口的框架是沙箱,但未设置"允许顶部导航"标记.

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

编辑:

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

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

document.addEventListener('error', receiveMessage, true);
function receiveMessage(error) {
    alert("iframe tried to unframe itself");
}
Run Code Online (Sandbox Code Playgroud)

Jer*_*ert 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!');
}
Run Code Online (Sandbox Code Playgroud)

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

您真正想要做的是捕获iframe 内部的错误(当沙盒脚本尝试访问时window.top),但由于同源策略,这是不可能的.顺便说一句,设置"allow-same-origin"沙盒标志只有在从origin顶级文档提供iframe内容时才会产生任何效果.例如,只要将iframe src或其他location内容更改为其他内容origin,就无法触及任何内部内容.

有多种方式可以跨越iframe边界进行交流,例如window.postMessage使用iframe或使用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>
Run Code Online (Sandbox Code Playgroud)

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


eve*_*een 0

例子:

有额外限制的:

<iframe src="demo_iframe_sandbox.htm" sandbox=""></iframe>
Run Code Online (Sandbox Code Playgroud)

Internet Explorer 10、Firefox、Chrome 和 Safari 支持沙箱属性。

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

定义和用法

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

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

HTML 4.01 和 HTML5 之间的差异

sandbox 属性是 HTML5 中的新属性。

句法

<iframe sandbox="value">
Run Code Online (Sandbox Code Playgroud)

属性值

  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,请获取对框架文档的引用并向其写入。这样做需要您设置允许同源沙箱标志。

<iframe id="myframe" sandbox="allow-scripts allow-same-origin" src="about:blank"></iframe>
Run Code Online (Sandbox Code Playgroud)
<script>
    var frame = document.getElementById("myframe");
    var fdoc = frame.contentDocument;

    fdoc.write("Hello world"); // or whatever
</script>
Run Code Online (Sandbox Code Playgroud)

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