Android webview拦截H5的接口请求并返回处理好的数据

Android webview拦截H5的接口请求并返回处理好的数据

Android 可以通过 WebViewshouldInterceptRequest 方法拦截到 H5 中的网络请求。这是一个 WebViewClient 中的回调方法,允许开发者在 WebView 发起网络请求时对其进行处理和修改。

具体使用方法如下:

  1. 你需要创建一个自定义的 WebViewClient,并重写 shouldInterceptRequest 方法。

  2. 在该方法中,你可以拦截 WebView 发起的网络请求,并返回一个自定义的响应,或让请求继续。

  3. 该方法在 API 21 (Android 5.0) 及更高版本中引入了两个重载方法:

    • shouldInterceptRequest(WebView view, String url) (API 11)
    • shouldInterceptRequest(WebView view, WebResourceRequest request) (API 21)

以下是代码示例:

// Kotlin 代码示例
webView.webViewClient = object : WebViewClient() {
    // 对于 API 21 及更高版本
    override fun shouldInterceptRequest(
        view: WebView, 
        request: WebResourceRequest
    ): WebResourceResponse? {
        val url = request.url.toString()
        // 这里你可以判断 URL,并根据需要拦截或修改请求
        if (url.contains("your_target_url")) {
            // 可以在这里做一些处理,例如替换请求或返回本地数据
            val inputStream = ... // 自定义输入流
            return WebResourceResponse("text/html", "UTF-8", inputStream)
        }
        // 不拦截,继续请求
        return super.shouldInterceptRequest(view, request)
    }
    
    // 对于 API 11 到 API 20 的设备
    override fun shouldInterceptRequest(
        view: WebView, 
        url: String
    ): WebResourceResponse? {
        // 这里处理逻辑类似于上面的代码
        if (url.contains("your_target_url")) {
            // 自定义处理逻辑
            val inputStream = ... 
            return WebResourceResponse("text/html", "UTF-8", inputStream)
        }
        return super.shouldInterceptRequest(view, url)
    }
}

shouldInterceptRequest 方法中,你可以返回一个 WebResourceResponse 对象,来改变或替换原始的网络请求,也可以通过默认实现让请求继续执行。

获取网络接口请求的数据(如 API 请求的响应),然后将其返回给 H5,

有以下几种方式可以考虑:

1. 拦截请求并手动发起请求

你可以通过 shouldInterceptRequest 方法拦截 WebView 的 API 请求,自己在 Java 或 Kotlin 中使用 HttpURLConnectionOkHttp 发起网络请求,处理完响应后,再将响应数据传递给 H5。

示例代码:

webView.webViewClient = object : WebViewClient() {
    override fun shouldInterceptRequest(
        view: WebView, 
        request: WebResourceRequest
    ): WebResourceResponse? {
        val url = request.url.toString()

        // 判断是否是需要拦截的接口请求
        if (url.contains("your_api_endpoint")) {
            // 通过 OkHttp 或 HttpURLConnection 发起请求
            val response = fetchApiData(url)

            // 将获取的响应内容传递给 H5
            view.post {
                view.evaluateJavascript("javascript:handleApiResponse('${response}')", null)
            }

            // 返回一个空响应或自定义内容
            return WebResourceResponse("application/json", "UTF-8", null)
        }

        return super.shouldInterceptRequest(view, request)
    }

    // 使用 OkHttp 发起网络请求(可以根据你的需求选择合适的网络库)
    private fun fetchApiData(url: String): String {
        // 简单 OkHttp 请求示例
        val client = OkHttpClient()
        val request = Request.Builder().url(url).build()

        client.newCall(request).execute().use { response ->
            return response.body?.string() ?: ""
        }
    }
}

在这个例子中,shouldInterceptRequest 会拦截指定的网络请求,然后用 OkHttp 发起请求,并将获取的响应数据通过 evaluateJavascript 方法传回到 WebView 中的 H5 页面。

2. 通过 WebView 和 H5 的 JavaScript 通信

另一种方式是通过 WebView 的 addJavascriptInterface 方法,将 Android 代码和 H5 进行通信。当 Android 发起请求后,可以通过接口将数据传递给 H5。

  1. 在 H5 中定义一个 JavaScript 函数,用于接收数据:

    function handleApiResponse(response) {
    console.log("API Response: ", response);
    // 这里可以对响应进行处理,渲染到页面等
    }

2. 在 Android 端:

webView.addJavascriptInterface(object {
    @JavascriptInterface
    fun sendDataToH5(data: String) {
        // 发送数据到 H5
        webView.evaluateJavascript("javascript:handleApiResponse('$data')", null)
    }
}, "AndroidInterface")

webView.webViewClient = object : WebViewClient() {
    override fun shouldInterceptRequest(
        view: WebView, 
        request: WebResourceRequest
    ): WebResourceResponse? {
        val url = request.url.toString()
        
        if (url.contains("your_api_endpoint")) {
            val response = fetchApiData(url)
            
            // 通过 JavaScript 接口传递数据到 H5
            view.post {
                view.evaluateJavascript("javascript:AndroidInterface.sendDataToH5('${response}')", null)
            }
            
            return WebResourceResponse("application/json", "UTF-8", null)
        }
        return super.shouldInterceptRequest(view, request)
    }
}

这种需要考虑到H5 发过来的网络接口请求类型吗post 还是 get

是的,在使用 shouldInterceptRequest 拦截 H5 发过来的网络请求时,需要考虑请求的类型(GET 或 POST)。这是因为 GET 和 POST 请求的处理方式不同,尤其是 POST 请求,它带有请求体(body)数据,而 GET 请求通常只包含 URL 参数。

shouldInterceptRequest 可以帮助你拦截请求,但对于 POST 请求的处理,需要特别注意提取和使用请求体。

如何区分 GET 和 POST 请求?

在 API 21 及更高版本中,shouldInterceptRequest 方法中的 WebResourceRequest 对象包含了更多信息,可以通过它的 getMethod() 方法来区分请求类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值