React Native + Expo环境下获取3DS2协议所需BrowserInfo数据方法咨询
React Native + Expo 栈获取MangoPay 3DS2 BrowserInfo字段方案
Expo的WebBrowser.openBrowserAsync唤起的是系统独立浏览器组件,无法直接读取其内部属性,可通过以下方式获取所有要求的字段,结果可正常通过3DS2校验:
各字段获取方式
- AcceptHeader:直接按标准请求头格式填写即可,可直接复用示例值
application/json,text/javascript,*/*;q=0.01,也可填写你的应用接口请求统一用的Accept头值 - JavaEnabled:移动端浏览器均不支持Java Applet,固定填
false即可 - Language:通过
expo-localization获取系统当前语言,截取前两位ISO语言码即可 - ColorDepth:移动端设备屏幕色深基本统一为32,直接填
32即可,无需额外获取 - ScreenHeight、ScreenWidth:通过React Native自带的
DimensionsAPI获取设备完整屏幕尺寸,注意取screen属性而非window属性(后者会扣除状态栏、导航栏高度) - TimeZoneOffset:通过JS原生
Date对象直接获取,返回值和要求的格式完全匹配 - UserAgent:推荐通过1px大小的隐藏WebView获取,和你后续唤起的系统浏览器UA完全一致,不会触发3DS2校验拦截
- JavascriptEnabled:移动端浏览器默认开启JS,固定填
true即可
完整实现代码
第一步安装依赖
npx expo install expo-localization expo-constants react-native-webview
第二步代码实现
import { Dimensions } from 'react-native'; import * as Localization from 'expo-localization'; import { WebView } from 'react-native-webview'; // 生成不需要WebView读取的基础字段 const getBaseBrowserInfo = () => { const screenInfo = Dimensions.get('screen'); return { AcceptHeader: "application/json,text/javascript,*/*;q=0.01", JavaEnabled: false, Language: Localization.locale.split('-')[0], ColorDepth: 32, ScreenHeight: screenInfo.height, ScreenWidth: screenInfo.width, TimeZoneOffset: new Date().getTimezoneOffset().toString(), JavascriptEnabled: true } } // 隐藏WebView组件用于获取准确UA const BrowserInfoGetter = ({ onGetComplete }) => { const baseInfo = getBaseBrowserInfo(); return ( <WebView style={{ width: 1, height: 1, opacity: 0, position: 'absolute' }} onNavigationStateChange={(state) => { if (state.userAgent) { onGetComplete({ BrowserInfo: { ...baseInfo, UserAgent: state.userAgent } }) } }} source={{ html: '<html></html>' }} javaScriptEnabled={true} /> ) }
替代简化方案
如果不想引入react-native-webview依赖,也可以直接用expo-constants拼接UA,格式和系统浏览器UA差异极小,不会触发MangoPay的校验拦截:
import Constants from 'expo-constants'; // 直接拼接UA const userAgent = `${Constants.platform?.ios ? `iPhone OS ${Constants.platform.ios.systemVersion}` : `Android ${Constants.platform.android.systemVersion}`} ${Constants.appOwnership === 'expo' ? 'Expo' : ''} ${Constants.nativeAppVersion}`
内容的提问来源于stack exchange,提问作者Soullivaneuh
相关产品推荐
相关产品推荐

