微信公众号首次授权登录,需两次才可返回原页面的问题解决方案

5,132 阅读3分钟

# 微信H5中webview页面多层history返回问题

  1. 微信H5授权获取用户信息采用的是oauth2方式,简单来讲,就是

    • 1.1 用户用过微信确认登录之后,微信方会返回一个授权码code给回第三方(接入方),这个授权码是一次性的,且有效期时间比较短;
    • 1.2 第三方通过此code去调用微信接口获取token,token的有效期也比较短;
    • 1.3 通过token再去调用微信平台接口,获取微信个人信息(昵称,头像地址,openid,unionid,地区……)
  2. 第一个oauth2的登录授权方式如下:

    • 2.1 通过重新赋值location.href,并传入服务号的appId以及redirect_uri跳转微信授权链接

    • 2.2 经过用户同意获取code;这里redirect_uri授权的页面地址,里面的location.host必须要经过授权才行,否则官方不会承认这个地址,也就不会返回code。 示例如下(具体配置参考官方文档)

      export const requestWxCode = () => {
          const REDIRECT_URI = [location.protocol, "//", location.host, location.pathname].join('')
          location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${APP_ID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=snsapi_userinfo&state=ok#wechat_redirect`
      }
      
  3. 授权回调域名过程:

    • 拿服务号的账号和密码登录微信管理后台,找到网页授权
    • ② 填写授权回调域
    • ③ 将MP_verify_NWxYqcEY0l6bdRam.txt下载下来上传至填写域名或路径指向的web服务器(或者虚拟主机)的目录;校验确保可以访问;
    • ④ 注意第三步,对于首次使用的域名,服务器根目录下是没有的,所以即便你在本地放置了,依旧是访问不到的;所以要么自己放置后部署,要么找运维手动放置;当可以点击“保存”时,就说明回调域名授权成功
  4. 此时一切都是顺利进行的,开发顺顺利利,以为完美,提测后……

^_^ 产品说: 第一次打开点击授权后重新加载了页面,下面出现了一个返回箭头,返回后还有上一个页面,上一个页面还是空白的……

@_@ 回答: 空白页面应该是没有用户信息前你要求的不展示界面任何内容,但是说明授权后页面栈增加了,变成了两个,应该是跳转API增加了页面栈,稍等我去看看

………………

然后把location.href 变成了location.replace() 最后发现然并卵

中午满头肿胀,打开其它的微信公众号网页,首次授权后发现都有这个问题,公司其它项目的公众号H5也有,中午去吃饭,用微信扫二维码支付,细致发现下面也出现返回箭头,点击也回到上一个空白页; 这样后就对解决这个问题,感到希望渺茫了;

可是产品说,我不管,我就要你解决这个问题。 想起了之前他的shuaiguo我只能瑟瑟发抖

  1. 问题回溯,通过oauth2授权,A1页面会重定向到A2页面,点击下方原生的返回按钮会返回到A1页面

  2. 解决方案: 通过history.pushState添加历史记录名目,history.onpopstate监听历史记录条目发生变化时,调用indow.WeixinJSBridge.invoke('closeWindow')直接关闭整个页面

// created中注册监听popstate状态变化
  window.addEventListener('popstate', () => {
      console.log('点击关闭')
      window.WeixinJSBridge.invoke('closeWindow')
  })

// 伪代码,获取查询参数
const code = getSearch('code'); 

if (code) {
  // code存在表示是页面A2
  history.pushState({page: 1}, null, window.location.href);
} else {
  // 页面A1 首次授权
  if (isWeixin()) {
      // 微信环境
      const REDIRECT_URI =encodeURIComponent(window.location.href)
      // 静默授权伪代码
      location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${APP_ID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=snsapi_userinfo&state=ok#wechat_redirect`
  } else {
      alert('当前不是微信环境');
  }
}