Android webview拦截请求,实现跨域处理

本文介绍如何通过重写WebViewClient的shouldInterceptRequest方法来实现WebView中的跨域请求处理,包括请求拦截、URL替换及参数修改,并展示了如何手动组装WebResourceResponse返回。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、重写WebViewClient 的 shouldInterceptRequest(),拦截请求,实现特殊处理(跨域处理)。

例如:拦截旧的url,替换域名,替换参数等,然后使用新url重新发起请求。

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun shouldInterceptRequest(
        view: WebView,
        request: WebResourceRequest
    ): WebResourceResponse? {
        request.url.toString().let {
        // 判断该请求是否需要拦截处理
            if (it.contains("xxx")) {
                return assembleResponse(view, request)
            }
        }
        //此处代表拦截器不处理该请求,直接原路请求器处理
        return super.shouldInterceptRequest(view, request)
    }

2、组装WebResourceResponse:

/**
     * 手动组装response
     */
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    private fun assembleResponse(
        view: WebView,
        request: WebResourceRequest
    ): WebResourceResponse? {
        try {
            val originUrl = request.url.toString()
            val realUrl = getRealUrl(originUrl)
            // val headers = request.requestHeaders
            val response = doGet(realPath, null).execute()
            
            if (response.isSuccessful && response.code() == 200) {
                return response.body()?.run {
                     WebResourceResponse(
				         response.header("Content-Type"),
				         response.header("Content-Encoding"),
				         response.body()?.byteStream()
				     )
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

3、网络请求–Get:

    private fun addHeader(builder: Request.Builder, headers: JSONObject?) {
        if (headers != null) {
            val keys = headers.keys()
            while (keys.hasNext()) {
                val key = keys.next()
                val value = headers.optString(key, "")
                builder.addHeader(key, value)
            }
        }
    }

    fun doGet(url: String?, headers: JSONObject?): Call? {
        var client: OkHttpClient? = null
        val trustManager = HttpUtils.getX509TrustManager()
        val okhttpBuilder = OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .writeTimeout(60, TimeUnit.SECONDS) // okhttp 已经有RetryAndFollowUpInterceptor
            .hostnameVerifier(HttpUtils.TrustAllHostnameVerifier())
            .addNetworkInterceptor(RemoveDirtyConnIntercepter())
            .sslSocketFactory(SSLSocketFactoryCompat(trustManager), trustManager)
        client = okhttpBuilder.build()

        val builder = Request.Builder().url(url)
        addHeader(builder, headers)
        val request = builder.get()
            .build()
        return client.newCall(request)
    }
WebViewAndroid处理请求通常通过设置其`WebSettings`的`JavaScriptEnabled`属性以及`DomStorageEnabled`属性,并允许同源策略例外。以下是关键步骤: 1. **启用JavaScript**: 如果你的应用需要处理来自JavaScript的请求,需要先开启`WebSettings.setJavaScriptEnabled(true);` 2. **配置同源策略** (CORS): 默认情况下,WebView受到同源策略限制,只能从相同的协议、名和端口发送请求。如果服务器设置了Access-Control-Allow-Origin响应头,允许特定的来源访问资源,那么WebView可以处理这些请求。 - 设置`WebViewClient`: 实现`shouldInterceptRequest()`方法,检查请求是否,如果是,可以根据服务器的Access-Control-Allow-Origin响应头来判断是否拦截。 ```java webView.setWebViewClient(new WebViewClient() { @Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { String origin = request.getUrl().getHost(); if (origin != null && !origin.equals("yourdomain.com")) { // 假设你想允许"yourdomain.com"访问 return super.shouldInterceptRequest(view, request); } return null; // 返回null表示允许请求继续 } }); ``` 3. **使用PostMessage或Fetch API**: 如果页面试图发起POST请求到其他,可以考虑利用`window.postMessage`来交互数据,或者在后台通过ServiceWorker代理网络请求。 需要注意的是,处理请求可能存在安全风险,尤其是当用户能够控制输入内容时,应谨慎设计和实施。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值