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

标签 javascript html iframe 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>

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

Unsafe JavaScript attempt to initiate navigation for frame with URL 'http://example.com' from frame with URL 'http://otherdomaian.com'. The frame attempting navigation of the top-level window is sandboxed, but the 'allow-top-navigation' flag is not set.

这很好,但我想捕获它,所以如果它发生,我会转到下一个 iframe。那么我如何捕捉到这种尝试呢?

编辑:

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

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

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

最佳答案

我是新来的,所以我没有足够的声誉来评论答案,如果我做错了,我深表歉意,但不幸的是,公认的解决方案将无法完成你正在寻找的东西。

我能够通过在 DOM 准备就绪后运行上面 JSFiddle 中的脚本来证明我的意思(不会有警报,但控制台中仍然有错误)。以下是有关该 fiddle 当前发生的情况的更多详细信息:

// 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>

很遗憾,如果没有您的第 3 方内容开发人员的帮助,我找不到任何方法在当前的浏览器实现中很好地做到这一点。我在 HTML5 规范中读到一些有趣的东西,可能允许我们在未来做这样的事情(不幸的是我已经用完了我可以在这里插入的链接数量),所以我会密切关注事情的进展。

关于javascript - html5 javascript-如何捕获从沙盒 iframe 中启动导航的尝试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21564860/

相关文章:

javascript - 淡出后淡出最后一个元素

javascript - 将购物车页面上的更新按钮从输入转换为 Shopify 中的 anchor 链接

iframe 中的 Javascript 日期选择器错误

javascript - 如何创建一个 Windows Phone 应用程序来解析网站中的 html 数据

javascript - 内联 block ul li 高度不适合

javascript - Fullpage js 停止在 iframe 内滚动

javascript - 在选项卡单击时加载 iframe

javascript - 从变量创建正则表达式的问题

使用 setTimeout 的 Javascript 打印

html - 灵活的盒子布局或网格布局或多列