Android WebView はリクエストをインターセプトしてクロスドメイン処理を実現します

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. ネットワークリクエスト – 以下を取得します。

    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)
    }

おすすめ

転載: blog.csdn.net/zhijiandedaima/article/details/127903455