我不确定我是否正确理解了您的最后评论。正如你所说的两个(对我来说)不同的事情:
- 您使用 plugin.jar(对我来说这意味着您的 java 调用 javascript 函数)
- “我从 Javascript 调用相同的函数”(这对我来说意味着你的 javascript 调用 java 函数)
我认为后者是正确的解释。
如果您只是调用 java 方法(通过 liveconnect)而不会做任何与安全相关的事情,一切都可以。你可以直接在你的javascript代码中做(假设applet带有id="myapplet")myapplet.safeMethod();。
从 javascript 调用 java 方法的主要问题是,这些方法通常只对 applet 进行限制,因为调用似乎在 JVM 中运行在与 applet 本身不同的上下文中。因此被视为非特权代码,您将获得AccessControlException。虽然例如就像在我的另一个答案中一样,由小程序本身执行的方法获得正确的权限并被执行。
现在,如果您在2.8 Security Model of JavaScript-to-Java Calls SUN states 部分阅读此LiveConnect Support in the New Java™ Plug-In Technology
当 JavaScript-to-Java 调用是
制作,JavaScript代码被建模
好像它来自一个
代码来源为的不受信任的小程序
文档库(即,
包含的目录
文件)。
我将其解读为:如果 applet 和 javascript 来自同一个站点,那么 javascript-to-java 调用应该以与 applet 本身相同的权限运行。在我们的例子中,这意味着我们在grant 中设置的任何权利。
但这仅适用于我的 Opera。 FF 和 IE6 都抛出AccessControlException。但它可能仍然适用于所有浏览器。
下面的代码有两个方法userName2()和userName()。 userName2() 所有浏览器中的 WFM。 userName() 仅适用于 Opera。通过按下 html 页面上的按钮进行检查。
如您所见,userName2() 不能像这样用于真正的用例(只能调用一次)。但是您可以在遇到类似问题时查看其他人提出的解决方案,并相应地扩展userName2()
Java Applet using LiveConnect
此外,您可能会考虑一些我没有尝试过的东西。所有来自 javascript-to-java 的调用都不会做任何与安全相关的事情,只是(如果需要)传入数据并立即返回。然后小程序执行实际工作(如上面显示的链接中所示)。然后,当完成后,小程序可以通过 JSObject (plugin.jar)
向 html 页面触发回调
TestApp.java
import java.applet.Applet;
import java.awt.*;
import java.security.AccessControlException;
public class TestApp extends Applet {
Label output = new Label("What is the value of user.name?");
String userName;
Thread access = new Thread() {
@Override
public void run() {
try {
userName = System.getProperty("user.name");
} catch (AccessControlException e) {
userName = "Oops, failed in thread. No read permissions!";
}
}
};
public void init() {
setLayout(new BorderLayout());
add(BorderLayout.CENTER, output);
}
public String userName2() throws InterruptedException {
access.start();
access.join();
output.setText(userName);
return userName;
}
public String userName() {
String userName = "Oops, failed in liveconnect-context. No read permissions!";
try {
userName = System.getProperty("user.name");
} catch (AccessControlException e) {
e.printStackTrace();
}
output.setText(userName);
return userName;
}
}
test.html
<html><head><title>test</title></head><body>
<applet id="myapplet" code="TestApp" width="350px" height="80px"></applet><br>
<input type="button" value="liveconnect version" onclick="javascript:alert(myapplet.userName());"><br>
<input type="button" value="hacky thread version" onclick="javascript:alert(myapplet.userName2());">
</body></html>
策略:.java.policy(在 C:/Documents and Settings/[USERNAME]/ 中手动创建/注意前导 .)
grant codeBase "http://[domain].xxx/-" {
permission java.util.PropertyPermission "user.name", "read";
};