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
相关产品推荐
相关产品推荐

