本文代码是基于jcef(Java Chromium嵌入式框架),jdk的Nashorn引擎(jdk8-jdk14)支持的js脚本,实现链接过滤与链接监听功能。
jcef的接口提供CefResourceRequestHandlerAdapter类来处理链接,在onBeforeResourceLoad和onResourceLoadComplete方法中可以完成链接过滤和监听功能
CefResourceRequestHandlerAdapter源码如下:
public abstract class CefResourceRequestHandlerAdapter implements CefResourceRequestHandler {
public CefResourceRequestHandlerAdapter() {
}
public CefCookieAccessFilter getCookieAccessFilter(CefBrowser var1, CefFrame var2, CefRequest var3) {
return null;
}
public boolean onBeforeResourceLoad(CefBrowser var1, CefFrame var2, CefRequest var3) {
return false;
}
public CefResourceHandler getResourceHandler(CefBrowser var1, CefFrame var2, CefRequest var3) {
return null;
}
public void onResourceRedirect(CefBrowser var1, CefFrame var2, CefRequest var3, CefResponse var4, StringRef var5) {
}
public boolean onResourceResponse(CefBrowser var1, CefFrame var2, CefRequest var3, CefResponse var4) {
return false;
}
public void onResourceLoadComplete(CefBrowser var1, CefFrame var2, CefRequest var3, CefResponse var4, Status var5, long var6) {
}
public void onProtocolExecution(CefBrowser var1, CefFrame var2, CefRequest var3, BoolRef var4) {
}
}
1、链接过滤实现
链接过滤实现很简单,onBeforeResourceLoad返回boolean值,false会继续请求链接,true停止请求。
2、链接监听
jcef自身没有直接提供链接内容的获取,但是可以在onResourceLoadComplete监听到所有成功请求,通过内置方法再次请求获取内容。
本文以https://my.oschina.net/penngo网址为例,屏蔽当前页面的个人头像链接和监控技能雷达接口内容
主要实现代码:
public class RequestHandler extends CefResourceRequestHandlerAdapter implements CefRequestHandler {
......省略代码
public void onResourceLoadComplete(CefBrowser browser, CefFrame frame, CefRequest request, CefResponse response, CefURLRequest.Status status, long var6) {
// 此处实现链接内容监听
String url = request.getURL();
String code = readTxt("monitor.js");
runcode(request, code);
}
@Override
public boolean onBeforeResourceLoad(CefBrowser browser, CefFrame frame, CefRequest request) {
// 此处实现链接过滤、广告屏蔽
String code = readTxt("filter.js");
if(code != null){
return runFilter(request, code);
}
else{
return false;
}
}
public void runcode(CefRequest request, String code){
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
try{
engine.put("request", request);
engine.put("CefURLRequestClientAdapter", com.jingji21.writing.webview.cef.CefURLRequestClientAdapter.class);
engine.put("CefURLRequest", org.cef.network.CefURLRequest.class);
engine.eval(code);
}
catch(Exception ex){
ex.printStackTrace();
}
}
public boolean runFilter(CefRequest request, String code){
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
try{
engine.put("request", request);
// 执行这个脚本
engine.eval(code);
Invocable invocable = (Invocable) engine;
Object result = invocable.invokeFunction("filter", request);
return (boolean)result;
}
catch(Exception ex){
ex.printStackTrace();
}
return false;
}
public String readTxt(String txtPath) {
File file = new File(txtPath);
if(file.isFile() && file.exists()){
try {
FileInputStream fileInputStream = new FileInputStream(file);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuffer sb = new StringBuffer();
String text = null;
while((text = bufferedReader.readLine()) != null){
sb.append(text);
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
......省略代码
}
屏蔽链接脚本filter.js
var System = Java.type('java.lang.System');
function filter(request){
if(request.getURL().equals("https://static.oschina.net/uploads/user/58/117179_200.gif?t=1380194723000") == true){
System.out.println("屏蔽链接=====" + request.getURL());
return true;
}
return false;
}
链接监控脚本monitor.js
var System = Java.type('java.lang.System');
/* System.out.println("onResourceLoadComplete=====" + request.getURL()); */
if(request.getURL().equals("https://my.oschina.net/penngo/radar/getUserPortraitRadarMap") == true){
System.out.println("监控链接=====" + request.getURL());
var CefURLRequest = CefURLRequest.static;
var cefURLRequestClientAdapter = CefURLRequestClientAdapter.static;
var Adapter = Java.extend(cefURLRequestClientAdapter);
var cefURLRequestClientAdapter = new Adapter(){
onRequestComplete : function(cefURLRequest) {
try {
var result = cefURLRequestClientAdapter.byteStream.toString("UTF-8");
System.out.println("监控内容=====:" + result);
} catch (e) {
e.printStackTrace();
}
}
};
CefURLRequest.create(request, cefURLRequestClientAdapter);
}
最后把RequestHandler添加到浏览器中
CefApp cefApp_ = CefApp.getInstance();
CefClient client_ = cefApp_.createClient();
client_.addRequestHandler(new RequestHandler());
运行效果
控制台输出