• 解决HtmlUnit执行JS报错提示ScriptException


    问题描述

    HtmlUnit作为一款比Selenium更轻量的HeadLess的Java版本浏览器模拟器,不需要在服务器上安装部署浏览器及其Driver程序。

    但是,众所周知,HtmlUnit对JS脚本的支持并不是很友好,GitHub中大部分的issue都和JS执行错误有关,作者也一直在升级JS Engine。

    笔者在实际使用过程中(HtmlUnit 4.1.0版本),也遇到了JS执行问题,并且issue、StackOverflow和google均未找到较好的解决方案。

    具体问题原因,是由于原站使用了ES6中的asyncawaitthen等关键字和方法。

    org.htmlunit.ScriptException: missing ; before statement (https://www.xxx.com/includes/js/common.js#322)
    	at org.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:963)
    	at org.htmlunit.corejs.javascript.Context.call(Context.java:585)
    	at org.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:481)
    	at org.htmlunit.javascript.HtmlUnitContextFactory.callSecured(HtmlUnitContextFactory.java:313)
    	at org.htmlunit.javascript.JavaScriptEngine.compile(JavaScriptEngine.java:735)
    	at org.htmlunit.javascript.JavaScriptEngine.compile(JavaScriptEngine.java:110)
    	at org.htmlunit.html.HtmlPage.loadJavaScriptFromUrl(HtmlPage.java:1124)
    	at org.htmlunit.html.HtmlPage.loadExternalJavaScriptFile(HtmlPage.java:1015)

    解决方法

    开始逆向思考,既然有这些不支持的关键字导致JS执行报错,能否在页面及JS资源加载时,修改网页及JS资源的源代码,过滤不支持的关键字。

    通过翻阅HtmlUnit官网文档,发现有个ScriptPreProcessor接口,可以通过钩子修改JS的执行代码,实现代码如下:

    this.browser.setScriptPreProcessor((htmlPage, sourceCode, sourceName, lineNumber, htmlElement) -> {
        // 处理HtmlUnit不支持ES6的async、await关键字,对js源码进行处理
        if (StringUtils.contains(sourceName, "tools.js")) {
            sourceCode = sourceCode.replace("async ", StringUtils.EMPTY);
            sourceCode = sourceCode.replace("await ", StringUtils.EMPTY);
        }
        
        return sourceCode;
    });

    大家可以根据自己遇到的具体问题,对sourceCode进行处理。

    最后再引申一下,如果有些JS对象不支持,可以分析原站JS代码,通过Java代替实现JS的逻辑,再通过变量赋值、修改JS源码的方式进行处理。

  • 相关阅读:
    Redis设计与实现(2)链表和链表节点
    CubeMX RTOS Demo
    使用Optional和直接返回null,哪个更好?
    使用jmx_exporter监控Kafka
    IDEA - 管理多个Git Remotes
    PL/SQL基本程序结构和语句(三)
    java培训课程之页面中获取国际化资源信息
    32个关键字详解①(C语言)
    Tomcat部署本地和服务器Springboot和Vue项目
    【Codeforces】Educational Codeforces Round 156 [Rated for Div. 2]
  • 原文地址:https://www.cnblogs.com/changxy-codest/p/18181093