Flutter iOS端InAppWebView无法加载reCAPTCHA问题求助
问题核心
iOS应用中通过InAppWebView加载含Google reCAPTCHA(V2/V3)的网页时,弹出JS提示“Connection to the reCAPTCHA is unavailable. Check your Internet connection and try again”。经排查,iOS端发起的reCAPTCHA AJAX请求存在URL缺失host的情况,而Android端无此问题,且通过ChromeSafariBrowser加载页面正常。
解决方案
1. 修复AJAX/Fetch请求的URL缺失问题
由于开启了useShouldInterceptAjaxRequest和useShouldInterceptFetchRequest,拦截逻辑可能导致相对路径的reCAPTCHA请求未正确补全host。可在拦截回调中手动修复请求URL:
// 处理AJAX请求拦截 @override Future<AjaxRequest?> shouldInterceptAjaxRequest(InAppWebViewController controller, AjaxRequest ajaxRequest) async { // 检测reCAPTCHA相关请求并补全host if (ajaxRequest.url?.host == null && ajaxRequest.url?.path.startsWith('/recaptcha/api') == true) { String fullPath = '${ajaxRequest.url?.path ?? ''}${ajaxRequest.url?.query != null ? '?${ajaxRequest.url?.query}' : ''}'; Uri fixedUri = Uri.parse('https://www.google.com$fullPath'); ajaxRequest.url = fixedUri; } // 返回null允许请求正常发送 return null; } // 同理处理Fetch请求 @override Future<FetchRequest?> shouldInterceptFetchRequest(InAppWebViewController controller, FetchRequest fetchRequest) async { if (fetchRequest.url?.host == null && fetchRequest.url?.path.startsWith('/recaptcha/api') == true) { String fullPath = '${fetchRequest.url?.path ?? ''}${fetchRequest.url?.query != null ? '?${fetchRequest.url?.query}' : ''}'; Uri fixedUri = Uri.parse('https://www.google.com$fullPath'); fetchRequest.url = fixedUri; } return null; }
2. 调整iOS端InAppWebView配置
在IOSInAppWebViewOptions中添加额外权限配置,确保reCAPTCHA相关资源可正常加载:
ios: IOSInAppWebViewOptions( allowsInlineMediaPlayback: true, sharedCookiesEnabled: true, // 允许跨域请求及第三方Cookie allowUniversalAccessFromFileURLs: true, allowFileAccess: true, )
3. 排查拦截逻辑是否过度拦截
暂时关闭useShouldInterceptAjaxRequest和useShouldInterceptFetchRequest选项,测试reCAPTCHA是否能正常加载。如果恢复正常,说明拦截逻辑中存在影响请求发送的代码,需逐步排查调整。
4. 升级InAppWebView版本
当前使用的flutter_inappwebview版本为^5.7.2+3,该版本可能存在URL解析的已知bug。建议升级至最新稳定版本,尝试修复底层问题。
5. 检查iOS ATS配置
确认项目info.plist中的NSAppTransportSecurity设置未阻止Google域名的HTTPS请求。若存在限制,可添加例外:
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>google.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSExceptionAllowsInsecureHTTPLoads</key> <false/> </dict> </dict> </dict>
内容的提问来源于stack exchange,提问作者Jakub Zelmanowicz

