React-Native开发鸿蒙NEXT-cookie设置

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,就直接拿来试试。依赖添加过程略过不表,参考

gitee.com/react-nativ...

直接使用Release里最新的6.2.1-0.0.8版本。页面逻辑也很简单

typescript 复制代码
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 && (
        <WebView
          bounces={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的情况,我承认这里面有赌的成分。

大概是这么个逻辑

typescript 复制代码
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秒去真实url
      setTimeout(() => {
        setUrl('真实页面url');
        setLoading(false);
      }, 1000);
    }
  }, [injectJS]);
  //    console.log('render里打log,仅供调试') moment().format('YYYYMMDDHHmmss')
  return (
    <View style={styles.bg}>
      <StatusBar barStyle={'default'} />
      {injectJS && (
        <WebView
          bounces={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>
  );
}

阴招毕竟是阴招,能走正常路数还是正常路数解决,除非伺候祖传代码。。。。。。


不经常在线,有问题可在微信公众号或者掘金社区私信留言

更多内容可关注

我的公众号悬空八只脚

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关推荐
一梦南柯3 小时前
HarmonyOS NEXT快速入手IBest-UI组件库
harmonyos
二流小码农4 小时前
鸿蒙开发:权限管理之权限声明
android·ios·harmonyos
全栈若城7 小时前
67.Harmonyos NEXT 图片预览组件之性能优化策略
性能优化·harmonyos·harmonyos next
觉醒法师7 小时前
HarmonyOS NEXT - 电商App实例三( 网络请求axios)
前端·华为·typescript·axios·harmonyos·ark-ts
全栈若城10 小时前
63.Harmonyos NEXT 图片预览组件之手势处理实现
华为·harmonyos·harmonyos next
Bowen_J10 小时前
HarmonyOS架构详解
华为·harmonyos·arkts
蓝枫Amy11 小时前
HarmonyOS应用程序包概述
程序员·harmonyos
ChinaDragon11 小时前
HarmonyOS:UIAbility组件启动模式
harmonyos
轻口味11 小时前
【每日学点HarmonyOS Next知识】状态栏字体、生命周期、自定义对话框屏幕中间、透明度、tab居中
pytorch·华为·harmonyos·harmonyosnext
林钟雪11 小时前
HarmonyNext实战:基于ArkTS的高性能图像处理应用开发
harmonyos