3

我想用 JavaScript 运行一个 HTML 页面,并想用 Java 访问它的输出。有没有办法在 Java 代码中访问浏览器的 JavaScript 控制台输出?

首先,我尝试使用 Java (htmlunit) 执行 JavaScript,但由于 JS 中的 jQuery,它给出了错误。

我需要执行的 JS 函数使用关联的 HTML 元素,这就是为什么我更喜欢保存页面、将我的 JS 添加到该页面并在本地运行它的原因。然后我可以在 JavaScript 控制台上看到输出,现在我想在 Java 代码中获取该输出以进行进一步处理。

4

5 回答 5

2

感谢大家的快速响应,我们使用 Greasemonkey 和 firefox 解决了这个问题。我们使用一个 servlet 将输出写入文件,而不是控制台。Greasemokey 中安装的 js 执行 js 方法和输出通过一个 Servlet(本地运行)获取请求并将输入写入文件,我们可以在 java 中使用该文件,内部文件写入代码只是添加同步块以防多个链接由 Greasemonkey 打开 :D

于 2012-09-11T19:54:35.423 回答
1

尝试Selenium访问该页面。它会打开一个真实的浏览器实例并单击(解决 jquery 问题),并且还应该能够获取console.log.

也许这个 JS 单元测试工具列表也可能对您有所帮助:适用于 TDD 的 JavaScript 单元测试工具

于 2012-09-08T21:06:09.393 回答
1

当然。慢慢阅读:

我得到的一个绝妙想法是,既然你正在运行 java,为什么不让它成为一个监听特定端口的服务器呢?你可以很容易地做到这一点。

一旦你有一个简单的线程在一个端口上监听,在你正在执行的任何 javascript 代码中,最后当你想将一些变量记录到控制台时,使用你想要发送的所有数据向这个本地服务器发送一个 ajax 调用到爪哇。

在服务器中收到请求后,将数据传递给其他线程并产生。

即使它看起来很复杂,对我来说似乎也是一个非常可行的解决方案。

于 2012-09-08T21:13:13.517 回答
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);
于 2015-10-19T21:52:19.733 回答
0

为了完成@MinuitJava 的回答,您还可以在错误事件上添加一个侦听器。

window.addEventListener('error', function (e) {
  console.log(e.type +  " : " + e.message + "\n");
  console.log(e);

  // var xhttp = new XMLHttpRequest();
  // code . . .
});

MDN 文档:窗口:错误事件

于 2021-02-12T06:32:22.707 回答