3DS2浏览器信息数据与React原生和Expo

kmbjn2e3  于 2023-02-24  发布在  React
关注(0)|答案(2)|浏览(116)

为了integrate the 3DS2 protocol我的支付提供商(MangoPay),我必须给出BrowserInfo数据。
下面是一个例子:

{
"BrowserInfo": {
        "AcceptHeader" : "application/json,text/javascript,*/*;q=0.01<", 
        "JavaEnabled": true,
        "Language":"fr",
        "ColorDepth": 32,
        "ScreenHeight": 667,
        "ScreenWidth": 375, 
        "TimeZoneOffset": "-120" 
        "UserAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148" 
        "JavascriptEnabled": true
}

目前,我可以使用WebBrowser.openBrowserAsync打开浏览器示例。
如何使用React Native + Expo检索这些信息?

zysjyyx4

zysjyyx41#

我发现唯一可行的方法是多步骤的过程。

公共网页

创建并托管公共网页,执行以下操作:
1.将浏览器信息提取到对象上
1.重定向到给定的重定向URL,其中包含以下信息
简而言之:

<!DOCTYPE html>
<html lang="en">
  <body>
    <script type="text/javascript">
      const browserInfo = {
        // Currently unable to fetch the default value automatically.
        // @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation/List_of_default_Accept_values
        acceptHeader: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        javaEnabled: window.navigator.javaEnabled(),
        language: window.navigator.language,
        colorDepth: window.screen.colorDepth,
        screenHeight: window.screen.availHeight,
        screenWidth: window.screen.availWidth,
        timeZoneOffset: window.navigator.timeZoneOffset,
        userAgent: window.navigator.userAgent,
        javascriptEnabled: true,
      }
      console.log('browserInfo', browserInfo);

      const urlParams = new URLSearchParams(window.location.search);

      if (urlParams.has('redirectUrl')) {
        const redirectUrl = new URL(urlParams.get('redirectUrl'));
        Object.entries(browserInfo).forEach(([key, value]) => {
          redirectUrl.searchParams.append(key, value);
        });
        document.location = redirectUrl.toString();
      }
    </script>
  </body>
</html>

Expo应用程序重定向获取

在世博会上,你有两件事要做:
1.启动事件侦听器以获取重定向
1.打开WebBrowser示例到上一个公共页面
示例:

import React, { FC, useCallback } from 'react';
import * as Linking from 'expo-linking';
import * as WebBrowser from 'expo-web-browser';
import * as queryString from 'query-string';
import {
  Button,
} from '@kidways/apps-components';
import {
  ButtonProps,
  View,
} from 'react-native';
import { useFocusEffect } from '@react-navigation/native';

const App: FC = () => {
  const urlEventHandler = (event) => {
    const parsedUrl = queryString.parseUrl(event.url);
    const path = parsedUrl.url.split('/--/')[1];

    if (
      path === 'browser-info'
    ) {
      // At this point, you have all the needed information.
      console.log('browser-info', parsedUrl.query);
    }
  };

  useFocusEffect(
    useCallback(() => {
      Linking.addEventListener('url', urlEventHandler);

      return () => Linking.removeEventListener('url', urlEventHandler);
    }, []),
  );

  const handleBrowserInfoTest: ButtonProps['onPress'] = () => {
    WebBrowser.openBrowserAsync(
      'https://your.domain/browser.html?redirectUrl='
      + Linking.createURL('browser-info')
    );
  }

  return (
    <View>
      <Button
        title="Browser Info"
        onPress={handleBrowserInfoTest}
      />
    </View>
  );
};

有了这段代码,您就可以通过按下按钮来获取浏览器信息。
这种解决方案并不理想,因为用户浏览器的开放性很难实现,但目前恐怕没有其他的办法。

zmeyuzjn

zmeyuzjn2#

使用WebView和一些JavaScript代码来回发一条带有所需浏览器信息的消息怎么样?
您可以将WebView HTML+JavaScript文档硬编码到React Native JavaScript文件中,如下所示(未经测试的代码,将其视为伪代码):

const mobileWebView3DsBrowserDataHtml = `
<!DOCTYPE html>
<html>
<body onload="post3DSBrowserInfo()">
<script>
function post3DSBrowserInfo() {
  var threeDsBrowserData = {
    java_enabled:
      typeof window.navigator.javaEnabled === 'function'
        ? window.navigator.javaEnabled()
        : false,
    language: window.navigator.language,
    color_depth: window.screen.colorDepth,
    screen_height: window.screen.height,
    screen_width: window.screen.width,
    timezone: new Date().getTimezoneOffset(),
  };
  window.ReactNativeWebView.postMessage(
    JSON.stringify({
      type: "3ds-browser-data",
      payload: threeDsBrowserData,
    })
  );
}
</script>
</body>
</html>
`

然后在WebView中使用它:

<WebView
  source={{
    html: mobileWebView3DsBrowserDataHtml,
  }}
  onMessage={event => {
    const browserDataMsg = JSON.parse(event?.nativeEvent?.data || {});
    if (browserDataMsg.type === '3ds-browser-data') {
      // do what you need with the browser info
      setBrowserData(browserDataMsg.payload);
    }
  }}
/>

或者您甚至可以使用JavaScript浏览器信息从服务器获取代码:

const mobileWebView3DsBrowserDataHtml =
  '<!DOCTYPE html><html><body></body></html>';

const MyComponent = () => {

  const [mobileWebView3DsBrowserDataJS, setMobileWebView3DsBrowserDataJS] = useState('');
  const [browserData, setBrowserData] = useState({});

  useFocusEffect(
    React.useCallback(() => {
      async function fetch3DsBrowserDataJS() {
        const js = await apiService.getBrowserDataJs();
        setMobileWebView3DsBrowserDataJS(js);
      }

      fetch3DsBrowserDataJS();
    }, []),
  );

  //...

从服务器获取的数据如下所示

(function () {
  var threeDsBrowserData = {
    java_enabled:
      typeof window.navigator.javaEnabled === 'function'
        ? window.navigator.javaEnabled()
        : false,
    language: window.navigator.language,
    color_depth: window.screen.colorDepth,
    screen_height: window.screen.height,
    screen_width: window.screen.width,
    timezone: new Date().getTimezoneOffset(),
  };
  window.ReactNativeWebView.postMessage(
    JSON.stringify({
      type: "3ds-browser-data",
      payload: threeDsBrowserData,
    })
  );
})()

然后在WebView中:

<WebView
  source={{
    html: mobileWebView3DsBrowserDataHtml,
  }}
  injectedJavaScript={mobileWebView3DsBrowserDataJS}
  onMessage={event => {
    const browserDataMsg = JSON.parse(event?.nativeEvent?.data || {});
    if (browserDataMsg.type === '3ds-browser-data') {
      setBrowserData(browserDataMsg.payload);
    }
  }}
/>

相关问题