I am injecting an iframe
in a tab
. Now inside the the iframe
, based on user's actions, I need to show some error/warning/success notifications
. However I want to display these notifications in the tab
not in iframe
. So I need to communicate between iframe
and content script
. Now these notifications
are dynamic based on user's actions so I thought of message passing
between iframe
and content script
via background page
.
So what i have done is send messages from iframe
to background
. Now both background page
and content script
listens to these messages but only background page
is able to receive them. On receiving messages it reflects them back to sender tab
. Now content script
can receive these messages as they are sent from background page
.
Now I tried the same using custom events
but it didn't work.
But i would like to know any other method which is more efficient than what i am doing??
EDIT : Here's the relevant code
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});
}
background.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;
}
});
content.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;
}
});
Using window.parent.postMessage
(not working):
iframe.js:
function sendMessageToContent(msg){
// chrome.runtime.sendMessage({type: msg});
window.parent.postMessage({ type: "fromFrame", message: msg }, "*");
}
content.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);
Also, when i add a breakpoint
at window.parent.postMessage({ type: "fromFrame", message: msg }, "*");
and try to see window.parent
object , inspected target
is disconnected. I don't why this is happening??
Yes, there's a more effective way to achieve it - using tabs.sendMessage
.
extensions cannot send messages to content scripts using this method. To send messages to content scripts, use tabs.sendMessage. (see runtime.sendMessage document )
Here's the code.
iframe.js:
chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
console.log(response.farewell);
});
content.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"});
You can also refer to https://developer.chrome.com/extensions/messaging#simple for more detail.
EDIT
Since iframe.js
is a content script, you should send the message with chrome.runtime.sendMessage
and without using chrome.tabs
API. Otherwise, chrome.tabs
will be undefined
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With