Flutter flutter_webview包支付场景下弹窗无法正常工作问题咨询
问题根因
flutter_webview默认关闭了多窗口支持,第三方支付环节普遍通过window.open语法触发新窗口加载收银台页面,默认配置下WebView会直接拦截这类新窗口请求,不会主动渲染内容,就会出现外部浏览器可正常打开、WebView内无响应的现象。
修复步骤
1. 启用多窗口支持
给WebView组件添加supportMultipleWindows: true配置,允许接收JS触发的新窗口请求。
2. 实现新窗口创建回调
添加onCreateWindow回调,在触发新窗口请求时,拿到目标地址直接用当前WebView加载即可,也可根据业务需要新开WebView实例加载。
3. 可选配置:处理JS系统弹窗
部分支付页会调用alert/confirm/prompt类JS弹窗,需要添加对应回调将其转换为Flutter原生Dialog,避免交互被拦截。
修复后完整代码
Expanded( child: WebView( debuggingEnabled: true, initialUrl: paymentUrl, allowsInlineMediaPlayback: true, javascriptMode: JavascriptMode.unrestricted, gestureNavigationEnabled: true, // 新增:启用多窗口支持 supportMultipleWindows: true, // 新增:处理混合内容,避免HTTP类支付页加载失败 mixedContentMode: MixedContentMode.compatibility, onWebViewCreated: (WebViewController webViewController) { _controller = webViewController; }, // 新增:处理新窗口创建请求 onCreateWindow: (CreateWindowAction action) { if (action.request.url != null) { // 直接用当前WebView加载新的支付页地址 _controller.loadUrl(action.request.url!); } return true; }, // 新增:处理JS alert弹窗 onJsAlert: (controller, jsAlertRequest) async { await showDialog( context: context, builder: (context) => AlertDialog( content: Text(jsAlertRequest.message), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text("确定"), ) ], ), ); return JsAlertResponse.handled(); }, onWebResourceError: (WebResourceError webviewerrr) { print("Handle your Error Page here"); }, javascriptChannels: Set.from([ JavascriptChannel( name: 'Alert', onMessageReceived: (JavascriptMessage message) { print(message.message); }, ) ]), ), ),
额外注意事项
- 安卓端如果加载的是HTTP协议的支付地址,需要在安卓项目中配置网络安全策略,允许HTTP请求,避免被系统拦截。
- 不要随意修改WebView的UA标识,部分支付渠道会校验请求来源UA,修改后可能导致支付校验失败。
- 支付完成后如果需要跳转回APP业务页,可以在
navigationDelegate回调中监听支付成功/失败的回调地址,拦截后直接执行原生页面跳转逻辑即可。
内容的提问来源于stack exchange,提问作者AbHi PoOjary
相关产品推荐
相关产品推荐

