看此答案之前,你应当看下我这篇文章不然你看不懂:https://blog.csdn.net/qq_38132283/article/details/102870957
上面的看完之后我相信你一定实现了自定义头信息或删除头信息。
那么应该怎么实现跨域?我们可用修改:sun.net.www.protocol.http.HttpURLConnection 里面的:getFilteredHeaderFields方法。因为:getHeaderFields 方法调用了getFilteredHeaderFields方法,所以我们通过注入字节码的方式重写此方法。
和上面的方式一样,我们先拦截类:sun.net.www.protocol.http.HttpURLConnection,这类是webview最终调用的
if ("sun/net/www/protocol/http/HttpURLConnection".equals(className)) {
try {
CtClass ctClass = classPool.makeClass(new ByteArrayInputStream(classfileBuffer));
CtMethod method = ctClass.getDeclaredMethod("getFilteredHeaderFields");
// 注入跨域代码
injectCrossDomain(method);
byteCode = ctClass.toBytecode();
ctClass.detach();
} catch (Exception e) {
e.printStackTrace();
throw new CatalinaException(e);
}
}
然后覆盖此方法,具体在方法:injectCrossDomain
/**
* 实现支持跨域
* @param method {@link #CROSS_DOMAIN_METHOD}
*/
private void injectCrossDomain(CtMethod method) throws CannotCompileException {
StringBuilder sb = new StringBuilder();
sb.append("if (this.filteredHeaders != null) {");
sb.append(" return this.filteredHeaders;");
sb.append("} else {");
sb.append(" java.util.HashMap var2 = new java.util.HashMap();");
sb.append(" java.util.Map var1;");
sb.append(" if (this.cachedHeaders != null) {");
sb.append(" var1 = this.cachedHeaders.getHeaders();");
sb.append(" } else {");
sb.append(" var1 = this.responses.getHeaders();");
sb.append(" }");
sb.append(" java.util.Iterator var3 = var1.entrySet().iterator();");
sb.append(" while(var3.hasNext()) {");
sb.append(" java.util.Map.Entry var4 = (java.util.Map.Entry)var3.next();");
sb.append(" String var5 = (String)var4.getKey();");
sb.append(" java.util.List var6 = (java.util.List)var4.getValue();");
sb.append(" java.util.ArrayList var7 = new java.util.ArrayList();");
sb.append(" java.util.Iterator var8 = var6.iterator();");
sb.append(" while(var8.hasNext()) {");
sb.append(" String var9 = (String)var8.next();");
sb.append(" String var10 = this.filterHeaderField(var5, var9);");
sb.append(" if (var10 != null) {");
sb.append(" var7.add(var10);");
sb.append(" }");
sb.append(" }");
sb.append(" if (!var7.isEmpty()) {");
// Access-Control-Allow-Origin
sb.append(" var2.put(\"Access-Control-Allow-Origin\", java.util.Collections.singletonList(\"*\"));");
// Access-Control-Allow-Headers
sb.append(" var2.put(\"Access-Control-Allow-Headers\", java.util.Collections.singletonList(\"*\"));");
sb.append(" var2.put(var5, java.util.Collections.unmodifiableList(var7));");
sb.append(" }");
sb.append(" }");
sb.append(" return this.filteredHeaders = java.util.Collections.unmodifiableMap(var2);");
sb.append("}");
// 重写整个方法
method.setBody(sb.toString());
}
这样我们就实现了跨域,我们可以在webview里面写任意的http请求。
注意这个类是http请求的,如果你的接口是https的可以尝试注入这个类:sun.net.www.protocol.https.DelegateHttpsURLConnection。但是我看这个类继承了:sun.net.www.protocol.http.HttpURLConnection,应该写上面的代码就可以了,不过你要测试一下!