最後のコメントを正しく理解できたかどうかわかりません。あなたが(私にとって)2つの異なることを述べているように:
- plugin.jar を使用します (これは、Java が JavaScript 関数を呼び出すことを意味します)
- 「私はJavascriptから同じ関数を呼び出します」(つまり、あなたのJavaScriptはJava関数を呼び出します)
後者の解釈が正しいと思います。
セキュリティ関連の処理を行わない Java メソッドを (liveconnect 経由で) 呼び出すだけであれば問題ありません。そして、JavaScriptコードで直接(アプレットを想定してid="myapplet"
)行うことができます。myapplet.safeMethod();
アプレットに対して通常は制限されていることを行う Java メソッドを JavaScript から呼び出す際の主な問題は、呼び出しが JVM とアプレット自体の異なるコンテキストで実行されているように見えることです。したがって、特権のないコードとして扱われ、AccessControlException
. たとえば、他の回答のように、アプレット自体によって実行されるメソッドは、適切な権限を取得して実行されます。
セクション2.8 JavaScript から Java への呼び出しのセキュリティ モデルSUN の状態の新しい Java™ プラグイン テクノロジでのこの LiveConnect サポートを読むと、
JavaScript から Java への呼び出しが行われると、JavaScript コードは、ドキュメント ベース (つまり、ドキュメントを含むディレクトリの URL) をコード元とする信頼できないアプレットから来ているかのようにモデル化されます。
私はこれを次のように読みました:アプレットとjavascriptが同じサイトからのものである場合、javascriptからjavaへの呼び出しはアプレット自体と同じ権限で実行する必要があります。私たちの場合、これは、 で設定したあらゆる権利を意味しますgrant
。
しかし、これは私にとってOperaでのみ機能します。FF と IE6 の両方がスローしAccessControlException
ます。ただし、すべてのブラウザーでうまくいく可能性があります。
次のコードには、 と の 2 つのメソッドがuserName2()
ありuserName()
ます。userName2()
すべてのブラウザーでの WFM。userName()
Opera でのみ動作します。htmlページのボタンを押して確認してください。
ご覧のとおりuserName2()
、実際のユースケースではこのように使用できません (一度しか呼び出せません)。ただし、同様の問題が発生したときに他の誰かが思いついた解決策を調べて、それに応じて拡張することができますuserName2()
LiveConnect を使用した Java アプレット
さらに、私が試していないことを検討するかもしれません。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";
};