rn登录后得到的token需要传递给网页,js获取到的浏览器信息需要传递给rn
RN Index.js:
import React from 'react'
import { WebView } from 'react-native-webview'
import useList from './useList'export default function Index(props) {const { uri, jsCode, webViewRef, handleMessage, handleLoad } = useList(props)return (<><WebViewref={webViewRef}source={{uri,}}style={{ flex: 1 }}injectedJavaScriptBeforeContentLoaded={jsCode} //injectedJavaScriptBeforeContentLoaded injectedJavaScriptoriginWhitelist={['*']}onMessage={(value) => handleMessage(value)}onLoad={() => handleLoad()}/></>)
}
RN useList.js:
import { useState, useEffect, useRef } from 'react'
import AsyncStorage from '@react-native-async-storage/async-storage'
import Constants from 'expo-constants'export default function useList() {let uri =Constants.manifest.extra.REACT_APP_MODE === 'dev'? `${Constants.manifest.extra.devHost}:3000/#/single/demo/test1`: 'https://chat.xutongbao.top/#/ai/chat'const webViewRef = useRef(null)const jsCode = `window.reactNative = {};window.reactNative.testData = 'inject data:1';true; // note: this is required, or you'll sometimes get silent failures
`const handleLoad = async () => {console.log('load')}const handleMessage = (value) => {let payload = value.nativeEvent?.data? JSON.parse(value.nativeEvent.data): {}let type = payload.typeif (type === 'getToken') {let fun = async () => {const token = await AsyncStorage.getItem('token')webViewRef.current.postMessage(JSON.stringify({type,token: token,}))}fun()webViewRef.current.postMessage(JSON.stringify({type: 'getBrowserInfo',}))} else if (type === 'getBrowserInfo') {console.log(payload)}}useEffect(() => {// eslint-disable-next-line}, [])return {uri,jsCode,webViewRef,handleMessage,handleLoad,}
}
网页 Index.js:
import React, { useState, useEffect } from 'react'
import uaParser from 'ua-parser-js'
import './index.css'export default function Index() {const [testData, setTestData] = useState()const [token, setToken] = useState()const handleGetDataFromInjected = () => {if (window.reactNative?.testData) {setTestData(window.reactNative?.testData)setToken(window.reactNative?.token)}}const handleGetToken = () => {window.ReactNativeWebView.postMessage(JSON.stringify({ type: 'getToken' }))}const handleMessage = () => {window.document.addEventListener('message', function (e) {let payload = e.data ? JSON.parse(e.data) : {}let type = payload.typeif (type === 'getToken') {setToken(payload.token)} else if (type === 'getBrowserInfo') {let ua = uaParser(navigator.userAgent)const { browser } = uawindow.ReactNativeWebView.postMessage(JSON.stringify({ type, browser }))}})}useEffect(() => {handleGetDataFromInjected()}, [])useEffect(() => {handleGetToken()}, [])useEffect(() => {handleMessage()}, [])return (<div className='m-test1'><div>{testData}</div><div>token:{token}</div></div>)
}
参考链接:
https://github.com/react-native-webview/react-native-webview/blob/eb2ce07e728352abe8b11d10a9de2a4fdc2f228b/docs/Guide.md#communicating-between-js-and-native
https://chat.xutongbao.top/