我想用JavaScript运行一个HTML页面,并想要用Java访问它的输出。有没有办法在Java代码中访问浏览器的JavaScript控制台输出?
首先,我尝试使用Java(htmlunit)执行JavaScript,但由于JS中的jQuery而导致错误。
我需要执行的JS函数使用关联的HTML元素,这就是我更喜欢保存页面,将JS添加到该页面并在本地运行的原因。然后我可以在JavaScript控制台上看到输出,现在我想用Java代码获取该输出以进行进一步处理。
答案 0 :(得分:1)
尝试Selenium访问页面。它会打开一个真实的浏览器实例并单击(解决jquery问题),并且还应该能够获取console.log
。
也许这个JS单元测试工具列表也可以帮到你:JavaScript unit test tools for TDD
答案 1 :(得分:1)
Ofcourse。慢慢阅读:
我得到的一个好主意是,既然你正在运行java,为什么不把它作为一个服务器来监听特定的端口呢?你可以很容易地做到这一点。
一旦你有一个简单的线程监听端口,你正在执行什么javascript代码,最后当你想将一些变量记录到控制台时,发送一个ajax调用到这个本地服务器包含你的所有数据想发送给java。
在服务器中收到请求后,将数据传递给其他线程并生成。
即使它看起来复杂,对我来说似乎是一个非常可行的解决方案。
答案 2 :(得分:1)
感谢大家的快速回复,我们使用Greasemonkey和firefox解决了这个问题。我们使用一个servlet将输出写入文件,而不是控制台。 greasemokey中安装的js执行js方法,并从中输出通过一个Servlet(本地运行)获取请求并将输入写入文件,我们可以在java中使用该文件,内部文件写入代码只是添加了synchronized块,以防多个链接由Greasemonkey打开:D
答案 3 :(得分:1)
我喜欢Prasanth的建议,这对我很有用。这是我的代码。
RCP:
logger = ...
private void startJSConsole() {
jsConsoleJob = new Job("JS Console Server") {
@Override
protected IStatus run(IProgressMonitor monitor) {
Socket connectionSocket = null;
try {
jsSocket = new ServerSocket(6789);
while (!monitor.isCanceled()) {
connectionSocket = jsSocket.accept();
readSocketData(connectionSocket);
}
} catch (IOException e) {
if (!"Socket closed".equals(e.getMessage())) {
logger.logError("Unable to open or read from Javascript console server socket", e);
}
return Status.CANCEL_STATUS;
} finally {
try {
if (jsSocket != null) {
jsSocket.close();
}
if (connectionSocket != null) {
connectionSocket.close();
}
} catch (IOException e) {
//pass
}
}
return Status.OK_STATUS;
}
};
jsConsoleJob.setUser(false);
jsConsoleJob.setSystem(true);
jsConsoleJob.schedule();
}
//I copied this code from here: http://stackoverflow.com/a/21729100/2036650
private void readSocketData(Socket connectionSocket) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
// read request
String line;
line = in.readLine();
StringBuilder raw = new StringBuilder();
raw.append("" + line);
boolean isPost = line.startsWith("POST");
int contentLength = 0;
while (!(line = in.readLine()).equals("")) {
raw.append('\n' + line);
if (isPost) {
final String contentHeader = "Content-Length: ";
if (line.startsWith(contentHeader)) {
contentLength = Integer.parseInt(line.substring(contentHeader.length()));
}
}
}
StringBuilder body = new StringBuilder();
if (isPost) {
int c = 0;
for (int i = 0; i < contentLength; i++) {
c = in.read();
body.append((char) c);
}
}
raw.append(body.toString());
System.err.println("JS: " + body.toString());
connectionSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
使用Javascript:
<html>
<head>
...
<script>
var global = global || {};
global.consoleLog = function(msg) {
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "http://localhost:6789", true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhttp.send(msg);
}
</script>
<script src="js/sigplot-minimized.js"></script>
</head>
<body>
...
</body>
</html>
然后从Javascript代码的任何地方:
global.consoleLog(logMessage);
答案 4 :(得分:0)
为了完成@MinuitJava 的回答,您还可以添加一个错误事件监听器。
window.addEventListener('error', function (e) {
console.log(e.type + " : " + e.message + "\n");
console.log(e);
// var xhttp = new XMLHttpRequest();
// code . . .
});
MDN 文档:Window: error event