Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome extension sending message from iFrame to event page then to content script

I have inserted an iframe from content script. It works fine. But if I want to display parent's html content on iframe, I have to use messaging to communicate between iframe and content script, but it doesn't work. Then I tries to send message from iframe to "event page" then to "content script". Once content script receives the message, it will query the html content and reply. It doesn't work either. How can I make it work?

content script:

var iframe = document.createElement('iframe');
iframe.id = "popup";
iframe.src = chrome.runtime.getURL('frame.html');
document.body.appendChild(iframe);

chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
  if (msg.from === 'event' && msg.method == 'ping') {
    sendResponse({ data: 'pong' });
  }
});

event page:

chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
  if (msg.from === 'popup' && msg.method === 'ping') {
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
       chrome.tabs.sendMessage(tabs[0].id, {
        from: 'event',
        method:'ping'}, function(response) {
          sendResponse(response.data);
      });
    });
  }
});

frame.js

// This callback function is never called, so no response is returned. 
// But I can see message's sent successfully to event page from logs.
chrome.runtime.sendMessage({from: 'popup', method:'ping'},
  function(response) {
  $timeout(function(){
    $scope.welcomeMsg = response;
  }, 0);
});
like image 458
angelokh Avatar asked May 13 '15 22:05

angelokh


1 Answers

I found a related question. https://stackoverflow.com/a/20077854/772481

From the documentation for chrome.runtime.onMessage.addListener:

This function becomes invalid when the event listener returns, unless you return true from the event listener to indicate you wish to send a response asynchronously (this will keep the message channel open to the other end until sendResponse is called).

So I have to return true to indicate the sendResponse is async.

event page:

chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
  if (msg.from === 'popup' && msg.method === 'ping') {
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
       chrome.tabs.sendMessage(tabs[0].id, {
        from: 'event',
        method:'ping'}, function(response) {
          sendResponse(response.data);
      });
    });
    return true; // <-- Indicate that sendResponse will be async
  }
});
like image 125
angelokh Avatar answered Oct 14 '22 18:10

angelokh