Calling JS from an applet works in Firefox & Chrom

2019-07-08 09:17发布

问题:

I have the following code in an applet to call some Javascript (it's a bit convoluted because the fn that's called gets an object from the DOM identified by divId and calls a function on it).

@Override
public final void start() {
  System.err.println("start() method called");
  this.javascript = JSObject.getWindow(this);
  this.jsObjectDivId = getParameter("parent_div_id");
  this.initCallbackFnName = getParameter("init_callback");
  Object args[] = {this.jsObjectDivId, this.initCallbackFnName};
  System.out.print("Calling init_callback\n");
  this.javascript.call("callJS", args);
}

The callJS function is:

window.callJS = function(divId, functionName, jsonArgString) {
  var args, obj;
  obj = $(divId).data('neatObject');
  args = eval(jsonArgString);
  return obj[functionName](args);
};

In Firefox/Chrome the divId and functionName arguments contain valid strings and everything works fine; the desired function is called on the object hanging off the specified DIV data.

In Safari, the divId and functionName arguments are both reported as a JavaRuntimeObject with values of true.

> divId
  JavaRuntimeObject
    true

What gives?

回答1:

LiveConnect is not fully supported in all browsers. Especially, Safari doesn't convert Java Strings to the prober JS equivalent when using call. In your case you can just use eval at the Applet side instead of call and put in a JSON string object with the arguments. Something like:

javascript.eval(callback + "({\"id\":\"" + id + "\",\" ... })")

Basically, you need to know the cross-browser compatible subset of LiveConnect that works. I've written a blog post that describes the subset: http://blog.aarhusworks.com/applets-missing-information-about-liveconnect-and-deployment/

It comes with a LiveConnect test suite which runs in the browser: http://www.jdams.org/live-connect-test



回答2:

I had a similar issue with calling a method on an applet in Safari. It was returning a JavaRuntimeObject that I caused an exception when it was user later on.

As pointed out by @edoloughlin I had to use (applet.getMethod() + "") after which point the proper string was evaluated.

The comment saved me a bunch of time so I thought it useful to add here as I can't comment above.