# Content script unable to send messages via send.port.emit

**URL:** <https://discourse.mozilla.org/t/content-script-unable-to-send-messages-via-send-port-emit/3922>\
**Category:** Development\
**Created:** [September 8, 2015, 9:17am UTC](https://discourse.mozilla.org/t/content-script-unable-to-send-messages-via-send-port-emit/3922 "2015-09-08T09:17:31Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![miguelg](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/miguelg/32/21058_2.png) [@miguelg](https://discourse.mozilla.org/u/miguelg)\
**Post date:** [September 8, 2015, 9:17am UTC](https://discourse.mozilla.org/t/content-script-unable-to-send-messages-via-send-port-emit/3922/1 "2015-09-08T09:17:32Z")

</div>

I have encountered undocumented behaviour in an SDK extension I am currently working on and would appreciate help from the community to find either a fix or a way around it.

The problem only occurs when an HTML page **embedded in the extension** is opened in a tab, like so:

`tabs.open(data.url("html/test.html"));`

Note that `test.html` above would reside in `data/html` from the extension’s root directory.

I’m injecting a content script and listening for messages emitted as given below:

```
tabs.once("open", function (tab) {
  var w = tab.attach({ contentScriptFile: [data.url("js/embed.js")]});

  w.port.once("init", function () {
    console.log("content script initialised");
  });
});

```

The content script, `data/js/embed.js`, contains the following:

```
console.log("attaching embedded script");
self.port.emit("init");

```

The problem is that if the content script is attached to a _data_ HTML page (a page embedded in the extension), messages sent by the content script are **suppressed**.

It is absolutely crucial that my extension opens an embedded HTML page and is able to both receive from and send messages to the extension. How can I overcome this limitation?

* * *

_I’ve created a tiny extension that reproduces the problem clearly. You can find it [here](https://www.dropbox.com/s/kytoxpj3l7nvd2l/test.zip?dl=1)._

---

<div class="post-metadata">

**Author:** ![miguelg](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/miguelg/32/21058_2.png) [@miguelg](https://discourse.mozilla.org/u/miguelg)\
**Post date:** [September 8, 2015, 11:41am UTC](https://discourse.mozilla.org/t/content-script-unable-to-send-messages-via-send-port-emit/3922/2 "2015-09-08T11:41:38Z")

</div>

Found a way of circumventing the limitation but it’s rather hacky. It consists of grabbing the content window object of the tab and then relying on the Window’s `postMessage` API. Like so:

```
var tabs = require("sdk/tabs"),
    self = require("sdk/self"),
    data = self.data,
    utils = require("sdk/tabs/utils"),
    {viewFor} = require("sdk/view/core");

tabs.once("ready", function (tab) {
  var window = utils.getTabContentWindow(viewFor(tab));
  window.addEventListener("message", function (ev) {
    console.log("message received: ", ev.data);
  });
});

tabs.open(data.url("html/test.html"));

```

Then in a script **loaded by the HTML page** , one would do something similar to:

`window.postMessage({ method: "init", state: true }, origin);`

I would still like to know why one can’t use the native `self.port.emit` API though? Or why it **quietly** suppresses attempts at emitting messages.

---

<div class="post-metadata">

**Author:** ![MartijnJ](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/martijnj/32/2849_2.png) [@MartijnJ](https://discourse.mozilla.org/u/MartijnJ)\
**Post date:** [September 8, 2015, 11:41am UTC](https://discourse.mozilla.org/t/content-script-unable-to-send-messages-via-send-port-emit/3922/3 "2015-09-08T11:41:58Z")

</div>

I think all you need to do is take your original script and change “open” to “ready”.

---

<div class="post-metadata">

**Author:** ![miguelg](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/miguelg/32/21058_2.png) [@miguelg](https://discourse.mozilla.org/u/miguelg)\
**Post date:** [September 8, 2015, 12:39pm UTC](https://discourse.mozilla.org/t/content-script-unable-to-send-messages-via-send-port-emit/3922/4 "2015-09-08T12:39:51Z")

</div>

Hmm, that’s strange.

When the opened tab refers to a web page (non extension), it is possible to emit messages to the content script in the tab’s `open` event. But _not_ so when the opened tab refers to an extension page – then, as MartinJ correctly says, the content script only receives the message if it is emitted in the `ready` event.

Why though?

Thank you, Martin, for the excellent observation!

---

<div class="post-metadata">

**Author:** ![MartijnJ](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/martijnj/32/2849_2.png) [@MartijnJ](https://discourse.mozilla.org/u/MartijnJ)\
**Post date:** [September 8, 2015, 2:27pm UTC](https://discourse.mozilla.org/t/content-script-unable-to-send-messages-via-send-port-emit/3922/5 "2015-09-08T14:27:51Z")

</div>

I think it’s supposed to fail in both cases.  
Think about it, when the tab opens there is nothing loaded yet, so what will your worker attach to.  
I think you might have tested the script against a cached page or something.  
In which case, it’s loaded instantly??

Just a guess.

---

<div class="post-metadata">

**Author:** ![miguelg](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/miguelg/32/21058_2.png) [@miguelg](https://discourse.mozilla.org/u/miguelg)\
**Post date:** [September 8, 2015, 2:35pm UTC](https://discourse.mozilla.org/t/content-script-unable-to-send-messages-via-send-port-emit/3922/6 "2015-09-08T14:35:57Z")

</div>

Yes, there is nothing loaded yet when the `open` event is triggered but that should be of no consequence since I’m specifically attaching a content script to the page with which the the addon attempts to communicate with. I argue that attaching the content script in the `open` or `ready` events _shouldn’t_ matter, especially since they run in their own execution contexts.
