Chrome extension and content scripts can communicate only in "inspect popup" mode

797 views Asked by At

I have this rather simple extention and content script:

manifest.json:

{
  "name": "My.First.App.Uses.Native.Api",
  "version": "1.0",
  "manifest_version": 2,
  "description": "My app uses my first Native Api",
  "icons": {
    "128": "icon-128__2.png"
  },
  "permissions": [
    "nativeMessaging", "activeTab"
  ],
  "browser_action": {"default_popup": "ext-page.htm"},
  "content_scripts": [
    {
      "matches": ["file:///*"],
      "js": ["content-script.js"]
    }
  ]
}

ext-script.js:

// Listen for messages that come from the client script.
chrome.runtime.onMessage.addListener(
  function( request, sender, sendResponse ) {
    if( request.greeting ) {
        //connectToNative();
        sendResponse( { farewell: request.greeting + ' -> received' } );
    }
  } );

content-script.js:

var btn = document.getElementById( 'mybutton' );
if( btn ) {
    btn.addEventListener( 'click', function() {
        var msg = document.getElementById( 'mytext' ).value;
        if( msg ) {
            chrome.runtime.sendMessage( { greeting: msg }, function( response ) {
                console.log( response.farewell );
            } );
            //port.postMessage({joke: "Knock knock"});
        }
        else {
            alert( "content script could not send message" );
        }
    } );
}

ext-page.htm:

<!DOCTYPE html>
<html>
<head>
    <script src='./ext-script.js'></script>
</head>
<body>
    This is a test Extention.
</body>
</html>

A sample page which the content script is injected in :

<html>
<head>
    <title>Connecting to a Chrome Extention using Content Script</title>
</head>

<body>
    <p>
        <!--<input id="btn" type="button" value="open document" />-->
        <input id="mytext" type="text" />
        <input id="mybutton" name="mybutton" type="button" value="open document" />
    </p>
</body>
</html>

My problem: If I select the extention and "inspect popup" it (meaning start the debug mode), and click mybutton button on my sample page, then I receive a message back from the extension and I can see it in my page's console. What I want is to get that message simply right after clicking that button in my sample page-- of course without debugging the extension. If I do not "inspect popup" the extension, then I receive this error message:

Error in event handler for (unknown): TypeError: Cannot read property 'farewell' of undefined

Thanks!

1

There are 1 answers

6
denikov On

I think because you're executing your alert inside main.js which is inside your popup, the popup needs to be open. Try inserting your alert inside background.js. Because background.js gets inserted into your sample page as a content_script, the alert should show up right in your sample page.

Instead of in background.js

    if( msg ) {
        chrome.extension.sendRequest( msg );
    }

Do

var msg = document.getElementById( 'mytext' ).value;
    if( msg ) {
        alert( msg );
    }

The docs suggest to have a manifest like this:

{
    "manifest_version": 2,
    "name": "Test",
    "version": "0.1",
    "background": {
    "scripts": ["background.js"],
    //this script is the main one which your extension communicates with
    "persistent": false
},
"browser_action": {
    "default_title": "BET",
    "default_popup": "popup.html"
    //this html file is the one that will be shown when clicked on your extension icon
},
"content_scripts": [{
    //this file will get injected into the tabs
    "matches": ["file:///*"],
    "js": ["content.js"]
}],
"permissions": [
    "tabs",
    "<all_urls>"
]

}

So inside your content.js your should have

chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
    console.log(response.farewell);
});

And inside background.js you receive the message

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    console.log(request.greeting);
    if (request.greeting == "hello")
        sendResponse({farewell: "goodbye"});
});

Doing it this way, you will be able to log what you sent from your injected script to your extension...just open the background console from the extensions page.

Hope this will help if you change the structure around a little. Let me know if it helps