【问题标题】:Prevent IFrame Navigation防止 IFrame 导航
【发布时间】:2013-02-21 23:19:00
【问题描述】:

我使用iframe 通过JS 将HTML 字符串写入其内容文档来显示HTML 电子邮件内容。如果用户单击显示的电子邮件中的链接,我不希望用户在该 iframe 内导航。现在我有这些选择:

  1. 在新的浏览器窗口或标签页中打开链接(首选
  2. 阻止所有导航(次优,仅当没有其他选项时)
  3. 我不知道更好的选择?

我怎样才能完成这两个选项中的任何一个?

我知道HTML5 引入了sandbox 属性,但不幸的是,它只适用于ChromeSafari,所以这不是一个选项。

【问题讨论】:

  • 使用 onclick 事件将所有链接转换为 span
  • 如果您正在为 iframe 文档编写 html,您应该可以在头部放置一个 元素。这将为在 iframe 中单击的链接打开一个新窗口或选项卡。
  • 不知道我可以在base 中设置目标。您应该将其发布为答案。
  • iframe 的沙盒属性现在被 IE10+ 和所有主流浏览器支持:caniuse.com/#feat=iframe-sandbox

标签: javascript html iframe


【解决方案1】:

对于 iframe 所在的页面,定义一个 CSP,将 child-src 限制为特定来源,例如域。仅供参考,这不适用于 Internet Explorer。这是一个相关的answer

【讨论】:

    【解决方案2】:

    如果 iframe 来自不同的来源,此方法将通过重置 iframe 源(如果它发生更改)来阻止导航:

      var $iframe = $('iframe');
      var iframeUrl = 'http://example.com/foo';
      var iframeLoaded = false;
      $iframe.on('load', function () {
        if (!iframeLoaded) {  # Allow initial load of iframe.
          iframeLoaded = true;
          return;
        }
    
        # Reset iframe location back to original source to prevent navigation.
        iframeLoaded = false;
        $iframe[0].src = iframeUrl;
      });
    

    很遗憾,无法检测到 iframe 加载的开始,因此它会在返回之前短暂闪烁新内容。另外,请注意,这会破坏浏览器的后退按钮。

    【讨论】:

      【解决方案3】:

      您应该能够将所有链接替换为其显示的文本,例如:

      var links = document.links;
      var i = links.length;
      var link, text, node;
      
      while (i--) {
        link = links[i];
        text = link.textContent || link.innerText || '';
        node = document.createTextNode(text);
        link.parentNode.replaceChild(node, link);
      }
      

      请注意,links collection 是实时的,因此是反向循环。

      【讨论】:

      • 这适用于所有浏览器吗? (我问您链接的文档是 Html 5,而 OP 说他想避免这种情况)。
      • document.links 是 DOM 0,DOM 方法都是版本 2 或更早版本,大约 NN 或 IE 5 以后的所有浏览器都支持这些。最新的是 textContentinnerText,但我认为从 IE 6 或 Firefox 1.5 开始的任何东西都应该这样做。
      【解决方案4】:

      您可以遍历 iframe 中的所有链接并将target="_blank" 添加到它们。

      (对不起,我只知道如何在 JQuery 中执行此操作,很抱歉在此链接示例而没有在问题中标记):

      $("#iframeID").contents().find("a").each(function() {
          $(this).attr("target", "_blank");
      });
      

      示例:http://jsfiddle.net/yP7Nd/ -(忽略我的 JQuery 代码上方的 JS 位,我必须这样做才能正确加载一些 IFrame 内容)。

      【讨论】:

      • 我想这是最优雅的解决方案,但最终它不会阻止通过 JS 触发的导航事件。也许我也应该删除所有onclick 等事件,但是如果在 iframe 中加载脚本后添加事件处理程序,我不确定该怎么做。
      • 如果框架是跨域的,这将不起作用。
      • 请注意 OP:I use an iframe to display HTML email contents by writing a HTML string to it's content document via JS。他正在自己设置内容,因此答案不适用于跨域。除非您控制源,否则您永远无法对 iFrame 内容进行任何操作。
      猜你喜欢
      • 1970-01-01
      • 2016-01-05
      • 2018-05-13
      • 2014-12-05
      • 2011-02-18
      • 2018-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多