Don’t Use JavaScript To Detect Browser

Just a word of warning – if you need to check for a specific version of Internet Explorer, do not rely on JavaScript. While working on a project where I was applying JavaScript to customize a closed-source package (yes, we were allowed to do this by the provider), we wanted to make sure that users were using only IE8 and up.

Fairly simple, right?

Well, no. It seems the package we were using was putting IE9 into quirks mode, which (much to my surprise) causes the user agent string to report the browser as IE7.

So, no JavaScript to detect the browser version.

On the server-side, the user agent was coming through correctly, so at least we had a different avenue on which we could proceed, but it seems rather peculiar that there would be no way to correctly identify a browser because of how it is rendering the page.

Error calling method on NPObject

I’ve had a bit of a problem with a Java Applet running in Safari on Windows. I have JavaScript code which attempts to invoke public methods in the Applet, but whenever I try to call these I get the error “Error calling method on NPObject”.

I’ve read a fair amount of BS “causes” (from things like “it’s a hidden DIV” to “Upgrade your JRE”), none of which proved to the the problem.

The real problem?

Safari doesn’t care if the applet is loaded before trying to invoke the methods.

Under Chrome, Opera, Firefox and even my much hated Internet Explorer, if you try to invoke a method on an applet which hasn’t loaded yet, the JavaScript runtime waits for the applet to complete, and then resumes. Safari does not.

So now, as part of the applet tag’s parameters, I have to include a method name which the applet must invoke in JavaScript, thereby guaranteeing that the applet is loaded and running.

Now I have the problem that apparently Safari is trying to execute JavaScript methods as URLs, thus causing a “Malformed URL” error.

Update:

After a bit of experimenting, it seems Safari does not like trying to pass and return non-String values. So, instead of using LiveConnect’s “call” method, you have to use “eval”, and don’t expect to be able to pass object around.