Search code examples
google-chrome-extensionmessage-passing

Message passing in Chrome Extension


I am quite confused about the what are counted as chrome extension view, which directly linked to what function I can use for passing messages between different components.

Let me just describe what I am trying to do first;

My background.html creates Desktop Notifications based on some events received from a node.js server through socket.io.

When the user clicks on the notification, I want to create a new tab pointing to a html within my extension (/src/view/token.html), and then send some data from the background.js (where my socket.io codes are) to the new tab. And I want to do this through message passing.

So, basically, i am doing

 var notification = webkitNotifications.createNotification(image, title, content);
 notification.onclick(function(e){

    chrome.tabs.create({url: "/src/view/tokens.html"}, function(tab){
        //just to make sure the tab is activated..
        chrome.tabs.onUpdated.addListener(function(tabId){
            if(tabId == tab.id) {
                chrome.tabs.sendMessage({data: whatever_data}, tabId); 
            }
        });
    });

 });

Now my problem is in my tokens.js (loaded in tokens.html), I try to listen for the message using:

chrome.extension.onMessage.addListener(function (msg, _, sendResponse) {
console.log(msg);
});

but I am getting "Uncaught TypeError: Cannot read property 'onMessage' of undefined:, so I assume that I don't have access to chrome.extension in the tokens.html???

I tried this with popup page (browser action popup) and option page, and they all worked just fine. So, I guess the view I created is just not a chrome extension page?

Now I am confused... 1) What are considered as chrome extension pages that have access to the chrome.* API 2) How should I implement what I want to do?

Thanks!


Solution

  • Problems in your code

    • chrome.tabs.sendMessage() wrong Invocation pattern
    • As complete code is not shared, i assume permissions are given to all pages, because manifest don't generate warnings for some set of values.
    • notification.onclick(function creates Uncaught TypeError: Property 'onclick' of object #<Notification> is not a function error

    Chrome.tabs.sendMessage

    Invocation form of chrome.tabs.sendMessage({data: whatever_data}, tabId); should be chrome.tabs.sendMessage(tabId,{"data": "whatever_data"}); (Tab id followed by message).

    notification.onclick(function

    Use notification.onclick = (function( assign handler to onclick property (because it is not a function)

    After fixing above problems i got your script running.

    manifest.json

    Registered background scripts and given all permissions needed.

    {
        "name": "Message Passing",
        "description": "This is used as a message passing",
        "version": "1",
        "manifest_version": 2,
        "background": {
            "scripts": [
                "background.js"
            ]
        },
        "permissions": [
            "notifications",
            "tabs"
        ]
    }
    

    background.js

    Modified code to eliminate errors

    //Created Notification
    var notification = webkitNotifications.createNotification("icon.jpg", "title", "content");
    //Added onclick property
    notification.onclick = (function (e) {
        //Created new tab
        chrome.tabs.create({
            url: "/src/view/notification.html"
        }, function (tab) {
            //just to make sure the tab is activated..
            chrome.tabs.onUpdated.addListener(function (tabId) {
                if (tabId == tab.id) {
                    //Send Mesage
                    chrome.tabs.sendMessage(tabId, {
                        "data": "whatever_data"
                    });
                }
            });
        });
    });
    notification.show();
    

    notification.html

    Ensure there is no inline script or <script> tag to comply with CSP.

    <html>
    
        <head>
            <script src="notification.js">
    
            </script>
        </head>
    
        <body>
            <p>This is a notification</p>
        </body>
    
    </html>
    

    notification.js

    Used your script with no changes!

    chrome.extension.onMessage.addListener(function (msg, _, sendResponse) {
        console.log(JSON.stringify(msg));
    });
    

    Output

    You can see message(s) being received in your new tab.

    enter image description here

    References