javafx webview cross domain 支持跨域 关闭同源策略

5 篇文章 0 订阅
2 篇文章 0 订阅

看此答案之前,你应当看下我这篇文章不然你看不懂: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,应该写上面的代码就可以了,不过你要测试一下!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值