如何从 chrome 扩展访问 iframe?

Posted

技术标签:

【中文标题】如何从 chrome 扩展访问 iframe?【英文标题】:How to access an iframe from chrome extension? 【发布时间】:2017-10-22 16:49:18 【问题描述】:

如何让我的扩展程序像 adblock 一样在所有帧上工作?

我尝试将"all_frames" : true 添加到我的清单文件中,但没有成功。

我尝试使用此代码获取具有特定 ID 的文本:

var theId = "starts with something";
var myArray = [];
$('[id^="theId"]').each(function(i, obj) 
    myArray.push($(this).text());
); 

$.unique(myArray);

console.log(myArray);

但它说我的数组是空的。当我检查页面上的元素时,我看到一个“顶层”层和一个“目标内容”层。该代码仅在我在“目标内容”层的控制台中执行时才有效。我可以在内容脚本中使用此代码,还是需要以某种方式使用 background.js?

【问题讨论】:

您好,作为您上一个问题的延续,我得到了一个可行的解决方案。 【参考方案1】:

Continued from SO44122853

我看到您发现内容是在 iframe 中加载的。所以我在这里有一个工作演示PLUNKER,sn-p 在这里,以防 plunker 出现故障。

详情见PLUNKER

演示

由于需要运行 2 个单独的页面而无法正常工作

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
  <style></style>
</head>

<body>
  <!--iframe is same as the one on the site, with the exception
  of the src-->
  
  <iframe id="ptifrmtgtframe" name="TargetContent" title="Main Content" frameborder="0" scrolling="auto" width='90%' src="tables.html"></iframe>
  
 <!--The data is displayed as a one string-->
  <output id='display'></output>
  
  <script>
  
  // Reference the iframe
    var iFID = document.getElementById("ptifrmtgtframe");
  // Register the load event on iframe
    iFID.onload = function(e) 
      // Callback is extractText function
      return extractText('#ptifrmtgtframe', '#display', '.PSLONGEDITBOX');
    

    /* Pass iframe and display as a single selector
    || Pass targets as a multiple selector
    */
    function extractText(iframe, display, targets) 
      var iArray = [];
      var iFrame = document.querySelector(iframe);
      var iView = document.querySelector(display);
      var iNode = "";
      
      /* .contentWindow is property that refers to content
      || that is in an iframe. This is the heart of the
      || demo.
      */
      var iContent = iFrame.contentDocument || iFrame.contentWindow.document;
      var iTarget = iContent.querySelectorAll(targets);
      
      /* .map() will call a function on each element
      || and return a new array as well.
      */
      Array.from(iTarget).map(function(node, idx) 

        iNode = node.textContent;
        iView.textContent += iNode;
        iArray.push(iNode);
        return iArray;
      );
      console.log(iArray);
    
  </script>
</body>

【讨论】:

注册一个事件监听器到被点击的按钮,并使用你的代码作为回调。 $('button').on('click', function(e) ..CALLBACK....); iframe 加载速度很慢,所以我使用了 onload 事件,这是加载页面期间的最后一个事件。您查看过Plunker 吗?选择器是您网站中使用的真实选择器。您需要做的就是添加您的扩展代码(例如exec.command()。) 是的,那将是一个更好的选择器,否则您将需要切换 129 个单元格。 原来我被愚弄了。它仍然无法正常工作。该代码仅在我将其键入到检查元素中“目标”层的控制台时才有效。知道为什么它不适用于所有帧吗? 刚刚用documentContent 选项更新了windowConent.document。 Chrome.ext 窗口对象似乎与 JS 窗口对象不同,因此 windowContent 属性将未定义。 documentContent 应该适用于 Chrome 分机。看到这个post和这个post 顺便说一句,在这一点上,我很确定就 DOM 收集而言,我们做得很好。我认为现在可能是 Chrome-ext 方面的问题。【参考方案2】:

我认为您的脚本可能在 DOM 加载之前执行,请尝试将您的函数放入其中:

document.addEventListener('DOMContentLoaded', function() 

);

编辑 该事件似乎在内容脚本中没有任何作用,我认为这是因为它们在 DOM 加载后已经加载,并且永远不会触发。

但是这似乎触发了,但不知道为什么:

$(function()
//something
);

这也需要注入 jQuery

【讨论】:

我如何检查这个?我不知道在哪里可以找到 console.log。另外,我以前试过这个,所以它可能不起作用 在内容脚本中,不是吗? 我试过 $(function() console.log("something"););在内容脚本中并被触发,但是 document.addEventListener('DOMContentLoaded'... 似乎没有被触发,试试这种方式 是的,它在内容脚本中。我在里面放了一个警报,没有弹出任何东西。仅当我将警报作为第一行时 这些 iframe 是否在同一个域中?我读过这可能是个问题。

以上是关于如何从 chrome 扩展访问 iframe?的主要内容,如果未能解决你的问题,请参考以下文章

从 chrome 的扩展内容脚本访问 iframe 内容

iframe如何在chrome扩展中访问父窗口

如何允许 chrome 扩展访问第三方 API 脚本?

使用 JQuery 访问由 chrome 扩展注入的 iframe

授予 Chrome 扩展程序访问 iframe 内容的权限

Pinterest 扩展如何(临时)存储网页中的图像,然后在 iframe 中访问它们?