gimite / web-socket-js

HTML5 Web Socket implementation powered by Flash
BSD 3-Clause "New" or "Revised" License
2.73k stars 489 forks source link

Error message: Error calling method on NPObject! #73

Closed jgehrcke closed 13 years ago

jgehrcke commented 13 years ago

Hey.

In web_socket.js, line 274:

WebSocket.__flash = document.getElementById("webSocketFlash");

document.getElementById() returns null under some circumstances, which I could not figure out until now. Then, in line 275:

WebSocket.__flash.setCallerUrl(location.href);

the error "Error calling method on NPObject!" is thrown. How can it happen that getElementById() on a valid ID returns null in the first place?

This is the same issue as already stated here: https://github.com/LearnBoost/Socket.IO-node/issues/243 -- but maybe here it is the better place to discuss.

Does anyone have a suggestion?

Thanks,

Jan-Philip Gehrcke

gimite commented 13 years ago

How did you check document.getElementById("webSocketFlash") actually returns null? My guess from the error message is that it actually returns DOM object but it fails to communicate with Flash. If WebSocket.__flash is null or undefined, the error message should be something like "accessing property of undefined". But I'm not sure why the communication fails...

jgehrcke commented 13 years ago

I should have added that I observed this using Firefox 4.0.1 in combination with Firebug. I created a breakpoint in line 275 of web_socket.js and watched the state of WebSocket.__flash. "Error calling method on NPObject" is thrown by line 275 if WebSocket.__flash == null. No error is thrown by line 275 if WebSocket.__flash == object#webSocketFlash.

jgehrcke commented 13 years ago

You had the correct feeling -- this seems to have been a domain policy issue and flash did not like setCallerUrl(location.href); with a specific value of location.href.

What I do not understand is why Firebug in this case states that WebSocket.__flash is null -- already one line before the crucial line. This looks like the application already went further than the breakpoint suggests.

JP

gimite commented 13 years ago

Do you know what kind of location.href causes the issue? Do you put SWF and HTML in different domains?

gimite commented 13 years ago

Also trying "Troubleshooting" section of README at https://github.com/gimite/web-socket-js may help.

jgehrcke commented 13 years ago

Yes, this was caused by calling the HTML from subdomain.host.xx, while the SWF was called from host.xx.

gimite commented 13 years ago

Yeah it doesn't work if SWF and HTML is in different domain. See "How to host HTML file and SWF file in different domains" section in README.

jpcarlino commented 13 years ago

Hello. I'm experiencing the same issue here.

My .swf file is located at a different URL than the HTML page, but even using the precompiled version of WebSocketMainInsecure.swf i'm getting exactly the same error in the same line. It seems i cannot call any method from WebSocket.__flash because i get the same error if i switch the order of the problematic line:

   console.debug("WebSocket.__flash = " + WebSocket.__flash);
   console.debug("WebSocket.__flash === null? " + (WebSocket.__flash === null));
   WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG);
   WebSocket.__flash.setCallerUrl(location.href);

the console output is:

WebSocket.__flash = [object HTMLObjectElement]
WebSocket.__flash === null? false
Error calling method on NPObject!
WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG); 

at that point i ensured the variable WEB_SOCKET_SWF_LOCATION is defined and has the right URL value. Also, the server policy file grants access for all domains (*). This doesn't happen if both swf and html are located on the same domain, so everything points to a crossdomain issue but i don't know what more can i try. Any clue?

Regards.

jpcarlino commented 13 years ago

More details of my scenario:

jpcarlino commented 13 years ago

I've solved it adding this line to WebSocketMainInsecure.as

Security.allowInsecureDomain("*");

Beause my swf file is served through https. Although my certificate was issued by a trusted authority i think it could relate to flash not accepting star certificates.

gimite commented 13 years ago

Thanks for the information. I added allowInsecureDomain in WebSocketMainInsecure.as at: https://github.com/gimite/web-socket-js/commit/5c7df9d52083c5320a305a6f3b89ef4b08c89c16

Since we have already allowed arbitrary domains, allowing HTTP -> HTTPS would not be more dangerous.