React Native Expo WebView组件无法打开支付OTP弹窗网页求助
React Native WebView 支付网关OTP弹窗无法捕获的解决办法
问题核心是:支付网关的OTP弹窗通常通过window.open创建新窗口,默认WebView不会触发onNavigationStateChange监听新窗口导航,需要开启多窗口支持并通过专门回调拦截新窗口请求。
步骤1:修改WebView组件配置
添加多窗口支持、JS启用等必要属性,并新增onCreateWindow回调处理新窗口:
import WebView from 'react-native-webview'; // 确保使用官方推荐的react-native-webview库 // ... 其他组件代码 <WebView source={{ uri: paymentUrl }} onNavigationStateChange={handleNavigationChange} onCreateWindow={handleCreateWindow} // 新增处理新窗口的回调 javaScriptEnabled={true} domStorageEnabled={true} supportMultipleWindows={true} // 开启多窗口支持 style={{ height: Dimensions.get('screen').height / 9.5, width: '100%' }} />
步骤2:实现新窗口拦截逻辑
添加handleCreateWindow函数捕获弹窗URL,处理OTP页面:
const handleCreateWindow = (event) => { const newWindowUrl = event.url; // 匹配OTP相关页面 if (newWindowUrl.includes('otp-confirmation') || newWindowUrl.includes('otp-page-url')) { setWebViewUrl(newWindowUrl); // 更新状态,用于显示OTP页面的WebView return true; // 允许创建新窗口,若需自行处理可返回false } // 其他新窗口请求按需处理 return false; };
步骤3:优化原导航状态处理
确保handleNavigationChange能正确捕获当前窗口的跳转(如支付成功/失败回调),同时可在OTP页面的WebView中绑定该函数,监听OTP流程完成:
const handleNavigationChange = (navState) => { const { url } = navState; // 处理支付失败回调 if (url.split('/')[4] === 'furl') { setPaymentUrl(''); setSnackbarMessage('Payment Failed, Please Try Again.'); setVisible(true); } // 处理支付成功回调 else if (url.split('/')[4] === 'surl') { submitHandler(); setPaymentUrl(''); setSnackbarMessage('Paid Successfully!'); setVisible(true); } // 处理当前窗口跳转至OTP页面的情况(部分网关用跳转而非弹窗) else if (url.includes('otp-confirmation') || url.includes('otp-page-url')) { setWebViewUrl(url); } };
关键说明
- 必须使用
react-native-webview库(而非旧内置WebView),上述属性才会生效; supportMultipleWindows={true}是开启新窗口监听的核心配置;- 若遇到用iframe/页面内模态框实现的OTP弹窗,可通过
injectJavaScript注入脚本监听弹窗触发事件,但这种场景较少见。
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

