Search code examples
javascriptoperapostmessageopera-extension

why can't post messages between background script and injected script in opera 12?


Since injected script can't do cross domain xmlhttp requests I tried, as it is advised in the manuals to send message from injected script to background script for it to do the job. But I cannot get the messages to work.

This is my code, it is only three files, as simple extension as it could be.

config.xml

<?xml version="1.0" encoding="utf-8"?>
<widget xmlns="http://www.w3.org/ns/widgets" id="http://www.example.org/helloworld">
  <name>postMessage-testcase</name>
  <description>check if opera's postMessage fails</description>
</widget>

index.html

<!doctype html>
<html lang="en">
<head>
<script>
  opera.extension.onmessage = function(event) {
    alert("get the message!");
    opera.extension.postMessage("posting reply");
  };
</script>
</head>
<body></body>
</html>

includes/user.js

// ==UserScript==
// @include     *apod.nasa.gov*
// ==/UserScript==

opera.extension.onmessage = function(event) {
  alert("got reply !");
};

alert("yep, I'm on apod, proceeding with messages");
opera.extension.postMessage("message body");

The script should send back and forth messages when user opens apod.nasa.gov, but only one msg is send here, no messaging is taking place, also no error show up in the console.


Solution

  • The opera.extension.postMessage() method cannot be called from the background process because it doesn't know which page/tab to post the message to. Instead, opera.extension.broadcastMessage() can be used to send a message to all tabs (see: http://dev.opera.com/articles/view/extensions-api-messaging-broadcastmessage/ )

    Alternatively, to send a message to the injected script in a particular tab:

    1. Listen for a connection event (opera.extension.onconnect) in the background process
    2. Run postMessage() from the event's source object

    See: http://dev.opera.com/articles/view/opera-extensions-messaging/#backgroundscript_injectedscript

    By the way, don't forget that what you use cross-domain XHR in the background process, you'll need to allow access to the target domain in your config.xml file, for example:

    <access origin="http://apod.nasa.gov" subdomains="true"/>