不管是用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