React-Native开发鸿蒙NEXT-cookie设置
应用有个积分商城,做一些积分兑换的业务,就一个基于react-native-webview开发的页面,在页面加载的时候通过js注入来设置cookie带入用户信息。
早先应甲方要求web网站关闭了,现在又要继续运行。于是就把web服务启动了,然后发现应用里积分商城还是进不去,然后就出事了。。。。。。
然后就开始找原因呗,在经过了几个然后之后,找到个前年写的钉钉文档里记录了当初为了应用加固做的操作,改了源码把js,dom什么的全禁了。
恢复了祖传代码,还有点问题:启动应用后,首次进入积分商城还是没有读到cookie,退出页面重进就好了。一番折腾想到是加载顺序的问题:webview里先加载了页面,页面加载后再注入js,这导致页面拿cookie的时候js还没注入完成。cookie是可以缓存的,所以退出页面后第二次进入会拿到第一次加载后注入的cookie。
自然而然想到了通过调整顺序来解决---先添加cookie,再请求url。看到有个专门处理cookie的第三方@react-native-oh-tpl/cookies,就直接拿来试试。依赖添加过程略过不表,参考
https://gitee.com/react-native-oh-library/usage-docs/blob/master/zh-cn/react-native-cookies-cookies.md#https://gitee.com/link?target=https%3A%2F%2Fgithub.com%2Freact-native-oh-library%2Freact-native-cookies%2Freleases。
直接使用Release里最新的6.2.1-0.0.8版本。页面逻辑也很简单
import CookieManager from '@react-native-oh-tpl/cookies';
export interface Cookie {name: string;value: string;path?: string;domain?: string;version?: string;expires?: string;secure?: boolean;httpOnly?: boolean;
}
export interface Cookies {[key: string]: Cookie;
}
function PageABC({navigation, route}): JSX.Element {const [loading, setLoading] = useState(true);const [url, setUrl] = useState('我是url');const expire = new Date(new Date().getTime() + 7 * 24 * 60 * 60,).toUTCString();const doInjectJS = async () => {await CookieManager.clearAll();const curCookie1: Cookie = {name: 'xxxxxx',value: 'xxxxxx',domain: 'xxx.yyy.zzz',path: '/',expires: expire,};let cookieResult1 = await CookieManager.set(url,curCookie1,true,);const curCookie2: Cookie = {name: 'yyyyyy',value: 'yyyyyy',domain: 'xxx.yyy.zzz',path: '/',expires: expire,};let cookieResult2 = await CookieManager.set(url,curCookie2,true,);console.log(cookieResult1 + ' ' + cookieResult2);setLoading(false);};/*** 模拟componentDidMount,即只运行一次该函数*/useEffect(() => {doInjectJS();return () => {};}, []);/*** 模拟componentDidUpdate,所有 state 值其中任意一个值变化了都会触发该函数*/useEffect(() => {});/*** 这个 effect 会在标签页获得焦点时运行*/useFocusEffect(React.useCallback(() => {}, []),);return (<View style={styles.bg}><StatusBar barStyle={'default'} />{!loading && (<WebViewbounces={false}style={{flex: 1}}source={{uri: url}}scalesPageToFit={true}startInLoadingState={true}// injectedJavaScript={injectJS}javaScriptEnabled={true}domStorageEnabled={true}useWebKit={true}onError={event => {console.log('收到webview onError = ' + JSON.stringify(event.nativeEvent),);}}onLoadEnd={event => {console.log('收到webview onLoadEnd = ' + JSON.stringify(event.nativeEvent),);}}onMessage={event => {console.log('收到webview onMessage = ' + JSON.stringify(event.nativeEvent),);}}/>)}{loading && (<View style={styles.loadingBg}><ActivityIndicator size="large" /></View>)}</View>);
}
目前发现的问题有:应用跳转的积分商城页面域名只能设置当前域名,不能将domain设置成父域名,比如当前域名是xxx.yyy.zzz,如果设置domain是.yyy.zzz就会设置失败,感觉可能是服务端跨域设置有问题?挺奇怪的。要不是做了一把clearAll()还发现不了。再议,再议。。。。。。
以上就是@react-native-oh-tpl/cookies设置页面cookie的方式。
=我是新时代与旧时代的分隔线===========
项目的鸿蒙RN版本是照着旧版app逻辑重新开发的,目前线上android/ios还是使用的旧版RN打包的版本。风烛残年的android/ios旧版已成传奇,那本当初开发用的旧笔记本专门供着这些个神仙工程。小尝试了下,拉取依赖都卡住了,用了个投机取巧的方式来应付:先去一个积分商城域名下的空页面,同时注入js,等个1秒钟再跳转到积分商城首页。这种方式在鸿蒙版本上也试了下,也可行。当然还是有小概率会遇到读取不到cookie的情况,我承认这里面有赌的成分。
大概是这么个逻辑
let documentJs ='一段设置cookie的js实现,存在一些变量字符需要替换';
function pageABC({navigation, route}): JSX.Element {const [loading, setLoading] = useState(true);const [injectJS, setInjectJS] = useState<string | null>(null);const [url, setUrl] = useState('空白页面url');// 这个重试不一定需要,测试发现老项目有存在第一次替换失败的情况,但打印global.XXX又是有值的,这里就用了多次尝试的方式来处理const doInjectJS = async () => {let retryCnt = 10; // 重试次数while (retryCnt > 0) {if (global.userid) {documentJs = documentJs.replace('变量', global.userid);}if (documentJs.indexOf('变量') == -1) {retryCnt = 0;setInjectJS(documentJs);} else {await new Promise(resolve => setTimeout(resolve, 100)); // 等待100ms重试retryCnt--;if (retryCnt == 0) {xnToast('积分商城加载失败,请尝试重新进入!');setInjectJS(documentJs);}}}};useEffect(() => {if (injectJS) {// 等1秒去真实urlsetTimeout(() => {setUrl('真实页面url');setLoading(false);}, 1000);}}, [injectJS]);// console.log('render里打log,仅供调试') moment().format('YYYYMMDDHHmmss')return (<View style={styles.bg}><StatusBar barStyle={'default'} />{injectJS && (<WebViewbounces={false}style={{flex: 1}}source={{uri: url}}scalesPageToFit={true}startInLoadingState={true}injectedJavaScript={injectJS}javaScriptEnabled={true}domStorageEnabled={true}useWebKit={true}onError={event => {console.log('收到webview onError = ' + JSON.stringify(event.nativeEvent),);}}onLoadEnd={event => {console.log('收到webview onLoadEnd = ' + JSON.stringify(event.nativeEvent),);}}onMessage={event => {console.log('收到webview onMessage = ' + JSON.stringify(event.nativeEvent),);}}/>)}{loading && (<View style={styles.loadingBg}><ActivityIndicator size="large" /></View>)}</View>);
}
阴招毕竟是阴招,能走正常路数还是正常路数解决,除非伺候祖传代码。。。。。。
不经常在线,有问题可在微信公众号或者掘金社区私信留言
更多内容可关注
我的公众号悬空八只脚
作者:悬空八只脚
链接:https://juejin.cn/post/7481533769053716491
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。