1

I inject an <iframe> on an origin webpage (youtube.com). What I want is to:

  1. Send an HTTP request to website A.
  2. Website A returns a json response.
  3. Update the iframe on origin webpage.

I just can't find a way to update iframe from content script.

Part of my manifest.json:

"content_scripts": [
  {
    "matches": ["https://www.youtube.com/watch?v=*"],
    "js": ["jquery-2.2.3.min.js", "content_script.js"],
    "all_frames": true,
    "run_at": "document_end"
  }
],

Part of my content script:

var iFrame  = document.createElement ("iframe");
iFrame.src  = chrome.extension.getURL("/template.html");
$('#watch-header').after(iFrame);

the result of above code:

<iframe src="chrome-extension://gdjehplmmeijdoijcnpbehoghnifhmib/template.html"></iframe>

I need an iframe so my image inside the template.html can correctly display.
sendMessage doesn't work, contentDocument also not working.

How to update the iframe anyway?

Xan
  • 74,770
  • 16
  • 179
  • 206
NamNamNam
  • 1,190
  • 3
  • 13
  • 22

1 Answers1

1

I was making a similar setup recently, and learned, much to my surprise, that iframes with extension pages inside web pages are treated as content script contexts.

Therefore, chrome.runtime.sendMessage doesn't reach them. However, chrome.tabs.sendMessage does, and it's the best way to communicate from the background page.

If you want to communicate with the content script of the parent page, a good way is to use postMessage:

// Content script in parent frame
// Assuming you have saved the reference to the frame in iFrame
function messageEmbed(message) {
  iFrame.contentWindow.postMessage(
    message,
    chrome.runtime.getURL("") // Origin of embedded page
  );
}

// Script in embedded HTML page
function messagePage(message) {
  window.parent.postMessage(
    message,
    "http://example.com/" // The expected origin of embedding page
                          // Can use "*" if not known in advance
  );
}

// Listener in both
window.addEventListener("message", function(event) {
  // Use event.data here as the message
});

Be warned that a hostile page can message the embed as well and there's no way to distinguish it save for using pre-shared key crypto. It's an unlikely risk though.


Final note, you mention the following:

I need an iframe so my image inside the template.html can correctly display

You may need to look into web_accessible_resources, perhaps you don't need this complication!

Community
  • 1
  • 1
Xan
  • 74,770
  • 16
  • 179
  • 206