浙政钉(浙里办小程序) H5 二次回退问题修复方案

H5页面接入浙里办之后,需要使用到浙里办的登录,其中登录分为法人登录及个人登录,我们这里采取的是个人登录也就是单点登录。
在接入单点登录后,H5界面需要返回两次才能返回到浙里办APP,这样的体验对用户来说不友好。借鉴了网上了的两种方法:一种是监听popstate,一种是监听pageshow。都没有达到想要的效果

使用popstate在次级页面返回的时候就会直接退到浙里办APP;使用pageshow,其中使用的判断window.performance.navigation.type 一直都是0,无法作为依据来判断

解决办法:

设置中转页。经测试,这样的写法在iPhone上,在切换账号、切换设备的时候获取不到loginResult页存储的token

一、使用空白页

设置应用的启动第一页为firstScreen

复制代码
//pages.json

"pages": [
        {
            "path": "pages/firstScreen/firstScreen",
            "style": {
                "navigationBarTitleText": ""
            }
        },
        {
            "path": "pages/home/home",
            "style": {
                "navigationBarTitleText": ""
            }
        },
        {
            "path": "pages/loginResult/loginResult",
            "style": {
                "navigationBarTitleText": "登录结果"
            }
        },
        ......
]

//firstScreen.vue

<template>
  <view class="firstScreen">
    {{ ticket ? "前往登录。。。。" : "首屏 应用启动页" }}
  </view>
</template>
 
<script>
export default {
  name: "firstScreen",
  components: {},
  props: {},
  data() {
    return { ticket: "" };
  },
  watch: {},
  computed: {},
  onLoad() {
    this.ticket = this.getTicketByUrl();
 
    if (!this.ticket) {
      if (!uni.getStorageSync("token")) {
        console.log("无ticket,没有token,重定向到首页  再重定向浙里办登录");
        this.goHome(true);
      } else {
        console.log("无ticket,有token,重定向到首页");
        this.goHome(false);
      }
    } else {
      console.log("有ticket,重定向到登录结果页");
      this.goLoginResult();
    }
  },
  created() {},
  mounted() {},
  methods: {
    // 截取url获取ticket
    getTicketByUrl() {
      let ticket = null;
      let reg = new RegExp("(^|&)" + "ticket" + "=([^&]*)(&|$)");
      let r = location.href.substr(1).match(reg);
      if (r != null) ticket = unescape(r[2]).replace("#/", "");
      console.log("截取url获取ticket--->", ticket);
      return ticket;
    },
    goHome(redrectTo) {
      uni.reLaunch({
        url: "/pages/home/home?redrectTo=" + redrectTo,
      });
    },
    goLoginResult() {
      uni.reLaunch({
        url: "/pages/loginResult/loginResult?ticket=" + this.ticket,
      });
    },
  },
};
</script>
<style scoped lang="scss">
.firstScreen {
}
</style>

2、新建一个loginResult页面,在该页面根据ticket去获取token

复制代码
<template>
  <view class="loginResult">
    <view> {{ loginResult ? "浙里办登录成功" : "登录中。。。" }}</view>
 
    <view @click="goBack" class="goBack" v-if="loginResult">
      返回首页
      <text v-if="loginResult">({{ backCount }}s)</text>
    </view>
  </view>
</template>
 
<script>
import { zwGoBack } from "@/util/zwUtil";
//根据浙里办RCP接口要求自定义封装的的接口请求方法
import { mgopRequest } from "@/request/mgop";
export default {
  name: "loginResult",
  components: {},
  props: {},
  data() {
    return {
      loginResult: false,
      backCount: 3,
      cleanIntervalFn: null,
    };
  },
  watch: {},
  computed: {},
  created() {},
  mounted() {},
  onLoad(option) {
    let ticket = option.ticket;
    this.getToken(ticket);
  },
  destroyed() {
    if (this.cleanIntervalFn) clearInterval(this.cleanIntervalFn);
  },
  methods: {
    goBack() {
      if (this.cleanIntervalFn) clearInterval(this.cleanIntervalFn);
      ZWJSBridge.onReady(() => {
        zwGoBack();
      });
    },
    getToken(ticket) {
      const data = {
        url: "mgop.ztzk.jtyszlb.token", //接口名称
        data: {
          //参数
          loginType: "zlb",
          ticket: ticket,
        },
      };
      mgopRequest(data).then((res) => {
        console.log(res, "zheliban浙里办");
        const resultCode = res.code; // 获取返回的请求状态码
        if (resultCode == 200) {
          uni.setStorageSync("token", res.data);
          this.loginResult = true;
          this.cleanIntervalFn = setInterval(() => {
            if (this.backCount > 0) this.backCount--;
            if (this.backCount === 0) {
              if (this.cleanIntervalFn) clearInterval(this.cleanIntervalFn);
              this.goBack();
            }
          }, 1000);
        } else {
          uni.showToast({ title: res.message, icon: "none" });
        }
      });
      console.log("浙里办ticket 2=====>", ticket);
    },
    // 截取url获取ticket
    getTicketByUrl() {
      let ticket = null;
      let reg = new RegExp("(^|&)" + "ticket" + "=([^&]*)(&|$)");
      let r = location.href.substr(1).match(reg);
      if (r != null) ticket = unescape(r[2]).replace("#/", "");
      console.log("截取url获取ticket--->", ticket);
      return ticket;
    },
  },
};
</script>
<style scoped lang="scss">
.loginResult {
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
 
  view {
    width: 100%;
    text-align: center;
  }
  .goBack {
    margin-top: 32rpx;
  }
}
</style>

3、应用首页home.vue,在该页面判断是否要重定向到浙里办登录页

复制代码
import { zwRedirectTo } from "@/util/zwUtil";
  
onLoad(option) {
    let redrectTo = option.redrectTo;
 
    ZWJSBridge.onReady(() => {
      console.log("初始化完成后,执行bridge方法", ZWJSBridge);
      
      if (redrectTo === "true")
        setTimeout(() => {
          zwRedirectTo();
        }, 1000);
    });
 
  },

4、浙政钉 H5 埋点代码

复制代码
// 浙里办登录重定向
export function zwRedirectTo() {
  let urlMobile ="https://puser.zjzwfw.gov.cn/sso/mobile.do?xxxxxx";
  let urlAlipay ="https://puser.zjzwfw.gov.cn/sso/alipay.do?xxxxxx";
  let url = "";
  let zwPlatform = checkZwPlatform();
  if (zwPlatform === "app") url = urlMobile;
  if (zwPlatform === "mini") url = urlAlipay;
  console.log("完整的重定向地址 = ", url);
  ZWJSBridge.openLink({ url: url });
}
// 检查平台 是浙里办APP 还是支付宝
export function checkZwPlatform() {
  const sUserAgent = window.navigator.userAgent.toLowerCase();
  // 浙里办APP
  const bIsDtDreamApp = sUserAgent.indexOf("dtdreamweb") > -1;
  // 支付宝小程序
  const bIsAlipayMini =
    sUserAgent.indexOf("miniprogram") > -1 && sUserAgent.indexOf("alipay") > -1;
 
  let result = "";
 
  if (bIsDtDreamApp === true) {
    result = "app";
  } else if (bIsAlipayMini === true) {
    result = "mini";
  }
  console.log("checkZwPlatform=", result);
  return result;
}
 
//判断是否是 android终端
export function isAndroid() {
  const sUserAgent = window.navigator.userAgent.toLowerCase();
  const isAndroid = sUserAgent.indexOf("android") > -1;
  return isAndroid;
}
 
// 浙里办的二次回退   实测 目前版本不需要区分浙里办APP、支付宝
export function zwGoBack() {
  ZWJSBridge.close()
      .then((result) => {
        console.log(result);
      })
      .catch((error) => {
        console.log(error);
      });
}

二、使用路由监听方式

可使用插件:https://github.com/devilwjp/uni-crazy-router/

复制代码
// 安装 uni-crazy-router
npm i uni-crazy-router -S

// 创建router/index.js

import Vue from 'vue'
import uniCrazyRouter from "uni-crazy-router";
Vue.use(uniCrazyRouter)

uniCrazyRouter.beforeEach(async (to, from ,next)=>{
    // 逻辑代码

    next()
})

uniCrazyRouter.afterEach((to, from)=>{
    // 逻辑代码

     const toUrl= to && to.url
     const fromUrl= from && from.url
     //首页回退到返回界面 :pages/authsso/backpage/backpage:中间件界面
     if( toUrl ==='pages/authsso/backpage/backpage' && fromUrl==='pages/index/index'){
    console.log(" >>> afterEach >>> ZWJSBridge.close ")
    ZWJSBridge.close({}).then(res => {
         console.log(res)
     }).catch(err => {
        console.log(err) 
        })
        }
        
})

uniCrazyRouter.onError((to, from)=>{
    // 逻辑代码

})
相关推荐
踩着两条虫2 小时前
揭秘VTJ.PRO前端架构:一套代码,多端运行的低代码引擎
前端·vue.js·低代码
fzil0012 小时前
用 React 写 CLI 是什么体验?—— Ink 框架深度解析与实战
前端·react.js·前端框架
长相思9792 小时前
text-overflow: ellipsis和display:flex互斥
前端·css·html
不像程序员的程序媛2 小时前
es查询是否存在某个字段
java·前端·elasticsearch
Highcharts.js2 小时前
React中频繁使用setState更新图表会影响性能
前端·javascript·react.js
zzginfo2 小时前
JavaScript 假值示例详解
开发语言·前端·javascript·ecmascript
CHU7290352 小时前
美护便捷预约,解锁精致生活——美业服务商城小程序前端功能解析
前端·小程序·生活
终端鹿2 小时前
Vue3 + axios 前后端联调实战:封装、跨域与报错处理
前端·vue.js·axios
研來如此3 小时前
C++ 接口设计 && Doxygen 注释
前端·javascript·c++