chrome.runtime.onmessage.addListener returns undefined sender object

4,235 views
Skip to first unread message

James Mortensen

unread,
May 8, 2013, 12:40:04 PM5/8/13
to chromi...@chromium.org
While poking around in the Chrome dev version to check the status of an unrelated bug, I noticed that the onmessage.addListener sender object doesn't contain the "tab" property in my packaged app.

The documentation for both Stable and Dev say the same thing, so I wonder if there's just a discrepancy in the documentation or if this is indeed an actual bug.  On Stable and Beta I get the tab object and can access the URL of the window, but on DEV, the tab object is undefined. The only available property is id; thus, I can't tell what page in my app made the request.


Here is what's in the documentation, but I'm not sure it makes sense to remove "tab" without replacing it with something to allow me to, for instance, tell that the request is coming from the background page and not some other window in my app.

Properties of MessageSender

tab optional tabs.Tab )
This property will only be present when the connection was opened from a tab or content script.
id ( string )
The ID of the extension/app that opened the connection.


Here is what I'm trying to access:

    console.info("sender page is " + sender.tab.url);   // returns an undefined error. 

error :: Error in event handler for 'undefined': Cannot read property 'url' of undefined TypeError: Cannot read property 'url' of undefined at chrome-extension://lgolnoceajfgiogkhdfpbjklkjledmka/SynclioLocalUI/phone.js:1111:82 at Event.dispatchToListener (event_bindings:356:21) at Event.dispatch_ (event_bindings:342:27) at Event.dispatch (event_bindings:362:17) at <error: illegal access> at Event.dispatchToListener (event_bindings:356:21) at Event.dispatch_ (event_bindings:342:27) at Event.dispatch (event_bindings:362:17) at Object.chromeHidden.Port.dispatchOnMessage (miscellaneous_bindings:273:22)


As a workaround, I could just pass the url of the sender in as a property along with the message, but that's kinda lame considering this worked out of the box.  So my question is this:

Is this a bug that I should report in the issue tracker, or was this done intentionally?  


Thank you!

James

Renato Mangini

unread,
May 8, 2013, 4:54:23 PM5/8/13
to James Mortensen, Chromium Apps

The answer to your question is in the documentation for trunk:

Properties of MessageSender

tab optional tabs.Tab )
The tabs.Tab which opened the connection, if any. This property will only be present when the connection was opened from a tab (including content scripts), and only if the receiver is an extension, not an app.

Renato Mangini | Chrome Developer Programs Engineer | man...@google.com | +55 11 2395-8608



James

--
You received this message because you are subscribed to the Google Groups "Chromium Apps" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-app...@chromium.org.
To post to this group, send email to chromi...@chromium.org.
Visit this group at http://groups.google.com/a/chromium.org/group/chromium-apps/?hl=en.
For more options, visit https://groups.google.com/a/chromium.org/groups/opt_out.
 
 

James Mortensen

unread,
May 8, 2013, 6:00:24 PM5/8/13
to chromi...@chromium.org, James Mortensen
Thanks Renato.  But this only answers one part of the question.  

but I'm not sure it makes sense to remove "tab" without replacing it with something to allow me to, for instance, tell that the request is coming from the background page and not some other window in my app.

I noticed in the trunk documentation there is a separate "url" property, and it doesn't say that it's limited only to extensions!  So I'm hoping this is intended to replace the value y'all removed.  However, when I try to access url in the code, it doesn't appear to be included in the object:

url optional string )
The URL of the page or frame that opened the connection. This property will only be present when the connection was opened from a tab (including content scripts).

Now, this isn't as explicit as the other message you cited.  It does not say this is available only to extensions, nor does it really make sense. Is this a bug?  How can a receiving endpoint know the sender?  Since this was purposely added as an additional property outside of the tab object, it seems reasonable that we've intended for this particular url object to represent *any* page's url that happened to open the connection.

Thanks,
James

Renato Mangini

unread,
May 8, 2013, 6:56:08 PM5/8/13
to James Mortensen, Chromium Apps

James,

Can you better explain your use case? Are you trying to communicate from windows inside your app or between different apps?

I think chrome.runtime.onMessage doesn't make sense for Chrome Packaged Apps (and if I'm right, it is a mistake to have it in the apps docs). 

So, to summarize, use:
- chrome.runtime.onExternalMessage for messaging with other apps and extensions (see the https://github.com/GoogleChrome/chrome-app-samples/tree/master/messaging sample)
- direct method calls for messaging with normal, non-sandboxed windows, including the background window, because they all live in the same process (save their handle in chrome.app.window.create callback);
- window.postMessage and window.addEventListener('message', callback) for messaging with sandboxed iframes and webviews;


Renato Mangini | Chrome Developer Programs Engineer | man...@google.com | +55 11 2395-8608


James Mortensen

unread,
May 8, 2013, 8:18:53 PM5/8/13
to chromi...@chromium.org, James Mortensen
I don't consider this a critical issue, now that I've had some time to think about it.  However, here is my use case below:

You can use chrome.runtime.sendMessage to send messages from one window to other windows in the packaged app.  Any window that has registered a listener using chrome.runtime.onMessage.addListener will receive the message.  I was able to verify this from the console of one of my open windows.

As an aside, the API for sendMessage doesn't have a parameter to allow you to specify which window to target; all windows receive the message.  In other words, if I have a phone.html and a settings.html, settings.html can pass some new data to phone.html -- or even to all open windows that are listening -- without needing to reload the entire window.  This, for instance, creates a smoother user experience, one where windows don't need to be reloaded simply to update their state.

As for why the URL property is important, let me explain:  As you can imagine, when you add a background page to the mix, and other windows, and communication between the windows is limited to passing asynchronous messages back and forth, debugging the application can become quite complex.

The main advantage the url property has for me is simply for debugging purposes.  It helps to be able to see where one process hands off control to another.  I wouldn't ever suggest anyone use the url for logic purposes, such as determining what action to take when a message is received, but it can be effective in helping developers understand the flow by looking at debug logs.  This is also helpful in debugging errors that involve tracing the flow backwards.  

I've thought about this a bit, and I'd say this isn't a critical issue by any means, and I can definitely live without this. So if you guys do mark this as not critical, we'll just simply either pass the url in manually, or we'll use the debugging tools built into Chrome.  I'd much prefer the packaged app UI bugs, WebRTC bugs such as the STUN binding issues, the --app-id startup flag bug get fixed instead, or perhaps we could see an API created for adding a system tray icon implemented. Those would be much more beneficial. :)

However, I wouldn't suggest removing this sendMessage or onMessage from the docs.  This documentation definitely is for Packaged apps, and the ability to communicate state between windows and the background page is critical to creating a "local" user experience.  

Hope this helps!  Please let me know if I can provide any more details.  Thank you again for the follow up!

James

Renato Mangini

unread,
May 8, 2013, 9:16:17 PM5/8/13
to James Mortensen, Chromium Apps

You are absolutely right, chrome.runtime.sendMessage is in for packaged apps. Sorry for my misguidance.


Renato Mangini | Chrome Developer Programs Engineer | man...@google.com | +55 11 2395-8608


Reply all
Reply to author
Forward
0 new messages