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、网络请求–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)
    }
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
WebView拦截非http链接,例如file://、tel://、mailto://等,可以通过重写shouldOverrideUrlLoading方法来实现。以下是示例代码: ```java webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.startsWith("http") || url.startsWith("https")) { // 如果链接以http或https开头,则继续加载链接 return false; } else { // 如果链接不是以http或https开头,则拦截链接并处理 if (url.startsWith("tel:")) { // 如果链接以tel:开头,则打电话 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url)); startActivity(intent); } else if (url.startsWith("mailto:")) { // 如果链接以mailto:开头,则发送邮件 Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("message/rfc822"); intent.putExtra(Intent.EXTRA_EMAIL, new String[]{url.substring(7)}); startActivity(Intent.createChooser(intent, "Send Email")); } else if (url.startsWith("file:")) { // 如果链接以file:开头,则打开本地文件 Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.parse(url), "application/pdf"); startActivity(intent); } return true; } } }); ``` 在上面的示例中,我们首先检查链接是否以http或https开头。如果是,则继续加载链接。如果链接不是以http或https开头,则根据链接的协议进行相应的处理。例如,如果链接以"tel:"开头,则打电话;如果链接以"mailto:"开头,则发送邮件;如果链接以"file:"开头,则打开本地文件。最后,返回true以拦截链接。 请注意,如果您需要在Android 7.0及更高版本上拦截非HTTP链接,建议您使用shouldOverrideUrlLoading(WebView view, WebResourceRequest request)方法,因为shouldOverrideUrlLoading(WebView view, String url)方法在7.0及更高版本上已经过时。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值