注入的 iframe 和内容脚本之间的通信——通过后台页面传递消息

Sid*_*Sid 7 google-chrome-extension

我正在注入iframe一个tab. 现在在 里面iframe,根据用户的操作,我需要显示一些error/warning/success notifications. 但是我想在tabnot in 中显示这些通知iframe。所以我需要在iframe和之间进行通信content script。现在这些notifications是基于用户操作的动态,所以我想到了message passingbetweeniframecontent scriptvia background page

所以我所做的是从iframeto发送消息background。现在无论是background pagecontent script听这些消息,但只background page能够接收他们。在接收消息时,它会将它们反映回sender tab. 现在content script可以接收从 发送的这些消息background page

现在我尝试了同样的使用,custom events但没有用。

但是我想知道比我正在做的更有效的任何其他方法?

编辑:这是相关的代码

iframe.js:

    $scope.hideFrame = function(){                                        
       sendMessageToBackground("hideFrame");
    };

     $scope.checkIfFormValid = function(){
       if(!($scope.taskName === "" || $scope.group.selectedGroup === null )){
          $scope.addTask();
        }
        else{
          sendMessageToBackground("invalidForm");
        }
     };

    function sendMessageToBackground(msg){
       chrome.runtime.sendMessage({type: msg});
    }
Run Code Online (Sandbox Code Playgroud)

背景.js:

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
   switch (request.type){

                case "hideFrame":
                   chrome.tabs.sendMessage(sender.tab.id,{type:"hideFrame"});
                   break;
                case "invalidForm":
                   chrome.tabs.sendMessage(sender.tab.id,{type:"invalidForm"});
                   break;

            }      
 });
Run Code Online (Sandbox Code Playgroud)

内容.js:

  chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
                switch (request.type){
                     case "invalidForm":
                         var n = noty({
                                        text        : ' Please fill all details',
                                        type        : 'error',
                                        layout      : 'topRight',
                                        timeout     :  10000,
                                        theme       : 'defaultTheme'
                                    });
                        break;

                    case "hideFrame":
                      $("#isolatedFrame").hide();
                      break;
                }      
    });
Run Code Online (Sandbox Code Playgroud)

使用window.parent.postMessage(不工作)

iframe.js:

 function sendMessageToContent(msg){
             // chrome.runtime.sendMessage({type: msg});
             window.parent.postMessage({ type: "fromFrame", message: msg }, "*");
            }
Run Code Online (Sandbox Code Playgroud)

内容.js:

window.addEventListener("message", function(event) {

  if (event.source != window)
    return;

  if (event.data.type && (event.data.type == "fromFrame")) {
    console.log("Content script received: " + event.data.message);

  }
}, false);
Run Code Online (Sandbox Code Playgroud)

此外,当我添加breakpointatwindow.parent.postMessage({ type: "fromFrame", message: msg }, "*");并尝试查看window.parentobject 时,inspected target已断开连接。我不明白为什么会这样??

小智 3

是的,有一种更有效的方法来实现它 - 使用tabs.sendMessage.

扩展无法使用此方法向内容脚本发送消息。要将消息发送到内容脚本,请使用 tabs.sendMessage。(参见runtime.sendMessage文档

这是代码。

iframe.js:

  chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
    console.log(response.farewell);
  });
Run Code Online (Sandbox Code Playgroud)

内容.js:

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
    console.log('greeting:", request.greeting);
    sendResponse({farewell: "goodbye"});
Run Code Online (Sandbox Code Playgroud)

您还可以参考https://developer.chrome.com/extensions/messaging#simple了解更多详细信息。

编辑

由于是内容脚本,因此您应该使用或不使用APIiframe.js来发送消息。否则,将会。chrome.runtime.sendMessagechrome.tabschrome.tabsundefined