设计支持多os的ssl-vpn客户端(二)
——java和js的通信
Tomqq 5/12/2008
Applet和js的通信有几种不同的方案可以选择,在这里我选择使用netscape.javascript.JSObject对象来进行。
举例如下:
a) java调用js
首先再applet里面引入包import netscape.javascript.JSObject;
然后申明一个win对象:
public static JSObject win;
在init函数里面进行初始化,win = JSObject.getWindow(this);
这样子就可以了,如果需要执行js函数(比如alert()),采用如下这种方式调用:
Client.win.eval("alert(\’hi,tomqq\’)");
看起来还是蛮简单的嘛,不过经过测试我发现,在连续刷新页面的情况下,如果每次都重新加载win对象,再firefox下会有加载失败的情况发生。在这个时候,我们可以用两个办法解决,一个是采用限制刷新的代码(php),
|
session_start(); $allow_sep = "3"; if (isset($_SESSION["post_sep"])) { if (time() - $_SESSION["post_sep"] < $allow_sep) { exit("Please refresh after 3 seconds."); } else { $_SESSION["post_sep"] = time(); } } else { $_SESSION["post_sep"] = time(); }
|
另一个是把win对象作为虚拟机静态变量,仅仅在页面加载的时候加载,刷新的时候不加载,就可以很好的解决这个问题。
b) js调用java
在这里,首先要对加载的applet进行申明,如下:
|
echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"; echo "<div align=\"center\">"; echo "<applet "; echo "codebase = \"download/\""; echo "code = \"multios.applet.Client\" "; echo "archive = \"multios.jar,AuthKit.jar\" "; echo "name = \"client\" "; echo "width = \"0\" "; echo "height = \"0\" "; echo "hspace = \"0\" "; echo "vspace = \"0\" "; echo "align = \"middle\" "; echo "mayscript =\"\" "; echo "> "; echo "</applet> ";
|
即加载一个0象素大小的applet,这个applet在页面不可见,不影响布局。另外注意的就是需要给这个applet对象起一个js能认识的名字,即:
echo "name = \"client\" ";这句话很重要。
Js调用applet的时候,可以这样子:
window.document.client.SStart.method(),直接跟client的java方法名和参数即可。
值得注意的是,js和applet通信,涉及到页面对于不同组件加载的问题,即:如果applet加载启动并开始调用js,而js函数还没有被页面加载完成,这怎么办?使用firedebug或者safari的html调试器查看可以看见各个元素的加载时序图,在这里,一般将js放在html页面前面,而把applet放在页面的最后,即可解决这个问题。
另外,某些通信操作可能会造成浏览器,如firefox的崩溃,具体原因分析为浏览器对jre支持引起的,这个问题解决,但是可以根据实际情况绕过。
最后还有一个问题就是安全性问题,js调用的applet方法如果使用了受限的本地操作怎么办?这个问题在后一章会专门讨论。
ps:当时写这篇文章的时候,汶川突发地震7.8特大地震,成都楼层晃动剧烈,当时什么都没有拿就跑出去了。事后知道周边死了很多人,一早来公司捐了款,上午继续完成了这篇文章。
为死难的同胞们默哀!