Flutter WebView URL追踪问题:支付跳转后无法自动退出页面
解决Flutter WebView无法追踪URL变化并自动退出页面的问题
问题说明
使用Flutter WebView加载支付页面,初始URL为https://myUrl/uk/checkout/......,需要在URL变为https://myUrl/uk/success/......或https://myUrl/uk/error/......时自动退出当前页面,但现有代码无法实现该功能。
问题分析
现有代码存在两个核心问题:
navigationDelegate直接返回NavigationDecision.prevent,阻止了所有页面导航,完全无法追踪URL变化- 缺少对页面加载完成后URL的检查,部分通过JS触发的内部跳转可能不会触发
navigationDelegate回调
修复后的代码
class PayWebWidget extends StatefulWidget { final TransferDataFromOrderHistoryModul dateFromOrder; const PayWebWidget({ super.key, required this.dateFromOrder, }); @override PayWebWidgetState createState() => PayWebWidgetState(); } class PayWebWidgetState extends State<PayWebWidget> { WebViewController? _controller; @override void initState() { super.initState(); if (Platform.isAndroid) WebView.platform = AndroidWebView(); } void _exitPage() { Navigator.of(context).pop(); } // 统一检查URL是否为支付结果页面 void _checkPaymentUrl(String url) { if (url.contains('/uk/success/') || url.contains('/uk/error/')) { _exitPage(); } } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: WebView( gestureNavigationEnabled: true, debuggingEnabled: true, javascriptMode: JavascriptMode.unrestricted, onWebViewCreated: (WebViewController webViewController) { _controller = webViewController; _controller?.loadUrl('https://myUrl/api/3/checkout/.....'); }, navigationDelegate: (NavigationRequest request) { _checkPaymentUrl(request.url); // 允许正常导航,仅在匹配结果URL时退出页面 return NavigationDecision.navigate; }, onPageFinished: (String url) { // 捕获JS触发的内部跳转,确保所有URL变化都被检测 _checkPaymentUrl(url); }, ), ), floatingActionButton: FloatingActionButton( onPressed: _exitPage, tooltip: '返回', child: const Icon(Icons.arrow_back), ), ); } }
关键修改说明
- 新增
_checkPaymentUrl方法,统一处理URL匹配逻辑,避免重复代码 - 修改
navigationDelegate:取消全局阻止导航,改为先检查目标URL,符合条件则退出页面,否则允许正常跳转 - 添加
onPageFinished回调:应对JS触发的内部跳转(这类跳转可能不会触发navigationDelegate),确保所有URL变化都能被检测 - 优化退出逻辑:使用
Navigator.of(context).pop()直接退出当前页面,替代原WebView回退的逻辑(原逻辑不符合需求)
内容的提问来源于stack exchange,提问作者Andrii Havrylyak
相关产品推荐
相关产品推荐

