如何从iframe中的内容脚本传回消息?

时间:2016-11-25 15:29:01

标签: javascript google-chrome google-chrome-extension

我正在查看嵌入了iframe的网页。我需要在网页和所有嵌入式iframe上从我的扩展程序浏览器操作中收集信息。我有以下代码:

清单

{
  "manifest_version": 2,
  ...
  "content_scripts": [
    {
      "all_frames": true,
      "js": [ "contentscript.js" ],
      "matches": [ "http://*/*", "https://*/*", "file:///*" ],
      "run_at": "document_start"
    }
  ],
  ...
}

浏览器操作弹出

chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
    chrome.tabs.sendMessage(tabs[0].id,{command: 'collectPageDetails'},function (details) {
        console.log('got details');
    });
});

内容脚本

chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
    if (msg.command === 'collectPageDetails') {
        console.log('getting page details');
        sendResponse({ details: 'something' });
        return true;
    }
});

我在这里看到的行为是主页面和iframe都收到了该消息。我可以通过在页面控制台中看到两个getting page details实例来验证这一点。

但是,我只收到一个回复​​浏览器操作的响应(got details仅在浏览器操作中记录一次),这似乎只来自主页而不是嵌入式iframe。

如何通过消息传递从页面中嵌入的iframe进行回传?我期待function (details) { }中的浏览器操作会发生两次回调。

1 个答案:

答案 0 :(得分:1)

来自chrome.runtime.onMessagesendRespnse()功能最多只能使用,以便向邮件发送单个响应。这并不意味着每帧可以使用一次,但总共一次。在描述sendResponse函数时,Chrome documentation说[强调我的]:

  

有响应时调用(最多一次)的功能。参数应该是任何可以使用JSON的对象。 如果同一文档中有多个onMessage侦听器,则只有一个可以发送响应。

因此,您需要使用其他一些向后台脚本发送消息的方法。这通常是chrome.runtime.sendMessage()(内容脚本)与后台脚本中的chrome.runtime.onMessage侦听器配对。您需要为消息建立一些格式,以定义背景脚本的消息。例如,您可以执行以下操作:

内容脚本:

chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
    if(msg.command === 'collectPageDetails') {
        console.log('getting page details');
        chrome.runtime.sendMessage({type:'collectPageDetailsResponse',details:'something'});
    }
});

后台脚本:

chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
    if(msg && msg.type === 'collectPageDetailsResponse') {
        //Received a details response.
        let tabId = sender.tab.id;
        let frameId = sender.tab.frameId;
        console.log('got details:', msg.details, ' From tabId:',tabId, ' frameId:',frameId);
    }
});