You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android WebView调用Google reCAPTCHA返回无效JSON的问题排查

Android WebView集成Google reCAPTCHA返回无效JSON(HTML响应)问题排查

问题现象

  • reCAPTCHA组件持续加载,重复请求地址:https://www.google.com/recaptcha/api2/reload?k=6Ldsle8jAAAAALx90hxvqSDQPFW-DdJ4qmqk219K
  • 前端报错:"Uncaught CustomError: Error in protected function: Invalid JSON string: HTTP method GET is not supported by this "
  • 接口实际返回HTML页面,而非预期的JSON格式数据

当前配置

WebView基础设置

domStorageEnabled = true;
javaScriptEnabled = true;

shouldInterceptRequest拦截实现

val httpClient = OkHttpClient()
val request: Request = Request.Builder()
    .url(url.trim { it <= ' ' })
    .addHeader("X-header", BuildConfig.RESET_USERNAME_PASSWORD_HEADER)
    .build()
val response: Response = httpClient.newCall(request).execute()
val headers: HashMap<String?, String?> = object : HashMap<String?, String?>() {
    init {
        put("Access-Control-Allow-Origin", "*")
        put("Access-Control-Allow-Methods", "*")
        put("Access-Control-Allow-Headers", "*")
        put("Content-Type", "*")
    }
}
WebResourceResponse(
    null, "UTF-8",
    200, "OK", headers, response.body?.byteStream()
)

问题修复方案

1. 保留原请求的HTTP方法

reCAPTCHA的/api2/reload接口必须用POST方法调用,但你的拦截代码默认用了GET,导致服务器返回不支持GET的错误HTML。修复时要完全复用原请求的方法和请求体:

// 获取WebView原请求的方法和请求体
val originalMethod = webResourceRequest.method
val originalRequestBody = if (originalMethod == "POST") {
    RequestBody.create(MediaType.parse(webResourceRequest.requestHeaders["Content-Type"]), webResourceRequest.requestBody)
} else null

val request: Request = Request.Builder()
    .url(url.trim { it <= ' ' })
    .method(originalMethod, originalRequestBody) // 保留原请求方法和体
    .addHeader("X-header", BuildConfig.RESET_USERNAME_PASSWORD_HEADER)
    // 复制原请求的所有必要头信息,比如Cookie、Content-Type等
    .build()

2. 修复响应头配置

  • 不要手动设置Content-Type: *,这是无效值,应该直接复用原响应的Content-Type,或者根据返回内容设置正确类型(比如JSON用application/json)
  • 无需手动添加CORS头,reCAPTCHA的请求属于同源请求,额外的CORS头会干扰解析,建议直接使用原响应的头信息:
    // 从OkHttp响应中提取原头信息,而非手动构造
    val responseHeaders = HashMap<String?, String?>()
    response.headers.forEach { name, value ->
        responseHeaders[name] = value
    }
    

3. 优化WebView配置

  • 确保开启必要设置:
    webView.apply {
        domStorageEnabled = true
        javaScriptEnabled = true
        allowFileAccess = true
        javaScriptCanOpenWindowsAutomatically = true // 部分reCAPTCHA场景需要
    }
    
  • 尽量避免拦截Google官方的reCAPTCHA接口,让WebView直接处理这些请求,减少自定义拦截带来的请求篡改风险。

内容的提问来源于stack exchange,提问作者Renz Manacmol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:39:59