JxBrowser-JS调用和AJAX数据监听

不管是用Jcef还是JxBrowser,很多时候我们的目的并不是为公司开发应用,而是为了方便自己做些不太善良的事,比如说js脚本注入。

通过JS脚本注入,我们可以丰富已有的网页上的功能。

执行网页JS的代码也很简单:

browser.executeJavaScript("document.title ='My title';");

但是很多情况下,JS脚本是混淆过的,很难分析。分析完后,东来西去在代码的汪洋里找自己需要的,好不容易才写出一个注入脚本。

有时可能仅仅是为了在某个按钮点击完成后执行自己想要的操作,或者是获取解密后的数据。

其实,不是所有事情都得靠注入解决,如果注入实在是麻烦,我们可以换个思路:直接替换加载的源码不就好了。

将完整的JS文件下载到本地,将混淆后的代码格式化一下,分析源码,根据需要修改代码,再在JxBrowser开始请求加载JS的时候,把JS指向我们本地的JS。不管混淆得如何花里胡哨,只要找到了正确的插入点,它几乎是骚不起来的。

拥有强大力量的JxBrowser里面可以很方便的实现这样的操作。(请查阅帮助文档 文献资料(Documentation)>载入内容(Loading Content))

编写一个DefaultNetworkDelegate的子类TestNetworkDelegateTranslate,重写onBeforeURLRequest方法,通过browser.getBrowserContext().getNetworkService().setNetworkDelegate(new TestNetworkDelegateTranslate());

public class TestNetworkDelegateTranslate extends DefaultNetworkDelegate{
 
    /*
     * 当即将发生请求时,将调用此方法。在建立任何TCP连接之前发送此事件,该事件可用于将请求重定向到另一个位置。
     * 该方法被同步调用。执行此方法时,URL请求将被阻止。如果此方法引发异常,则将使用默认行为-目标URL将不会更改。
     * params:提供有关请求URL和HTTP方法的信息(“ GET”,“ POST”等)。要覆盖目标URL,请使用  RequestParams.setURL(String)  方法。
     */
    @Override
    public void onBeforeURLRequest(BeforeURLRequestParams params) {
        System.out.println("可以被修改请求的URL:"+params.getURL());
//      params.setURL("");
        if(params.getURL().startsWith("https://xxx/xxx.js")) {
            params.setURL("file:///d:\xxx.js");
        }
        super.onBeforeURLRequest(params);
    }
}

有时候我们需要监听ajax数据,JxBrowser里面有提供此功能,还是使用DefaultNetworkDelegate。

public class XymNetworkDelegateTranslate extends DefaultNetworkDelegate{
     
    @Override
    public void onDataReceived(DataReceivedParams params) {
//        System.out.println("数据到达...");
        String url=params.getURL();
//        System.out.println("URL:"+params.getURL());
        if(url.indexOf("xxxxxxxx")!=-1) {
            System.out.println("接收数据URL..."+url);
            String data = new String(params.getData(),Charset.forName("UTF-8"));
            System.out.println("data = " + data);
        }
         
        super.onDataReceived(params);
    }
}

这里的代码在数据量很大时会有问题(比如说获取JS文件内容),因为数据会分多次接收,可以使用onDataReceived和onCompleted组合。

然而这也会产生一个问题,DefaultNetworkDelegate这个类运行时间长了后,偶尔会出现问题,譬如先执行了onCompleted,再执行onDataReceived。所以最好还是用脚本注入的形式。

如果ajax获取的数据不是很大,只使用onDataReceived就行了。

public class XymNetworkDelegate extends DefaultNetworkDelegate{
 
    List < byte[] > blist=new ArrayList();
 
    @Override
    public void onDataReceived(DataReceivedParams params) {
//        System.out.println("数据到达...");
        String url=params.getURL();
//        System.out.println("URL:"+params.getURL());
        if(url.indexOf("xxxx")!=-1) {
            System.out.println("接收数据...");
            blist.add(params.getData());
        }
         
        super.onDataReceived(params);
    }
 
    @Override
    public void onCompleted(RequestCompletedParams params) {
        String url=params.getURL();
        if(url.indexOf("xxxx")!=-1) {
            System.out.println("数据接收完成...");
            try {
                saveByteList();
            }catch(Exception e) {
                e.printStackTrace();
            }
            blist.clear();
        }
         
        super.onCompleted(params);
    }
     
    public void saveByteList() {
        if(blist.isEmpty()) {
            return;
        }
        int length=0;
        for(int i=0;i

 

你可能感兴趣的:(JxBrowser经验)