微信公众号h5获取openid(history模式和hash模式)

记录最近项目遇到的问题

vue开发的h5页面,需要获取扫码用户的微信openid,以前用的都是history模式,这次用的是hash模式,文章两种情况都会讲到。
微信获得授权官方地址
1.history模式
在config文件夹下定义一个js文件方便使用(例如:defaultSettings.js)

function urlencode (str) {  //转换一下location,主要针对hash的#
  str = (str + '').toString();   
  return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').
    replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+').replace(/#/g, '%23');  
  
}
export const WX_CONFIG = {
   appid: 'wx606f2d67dc8aaa74',//测试微信账户
   appsecret: '07209d9a9b4f8c9290771d67bcd07888',//测试微信账户
   location: window.location.href,//测试url
  redirect () {
  // 路径里面不允许用#,会报redirect_uri参数有误
    window.location.href =  `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${this.appid}&redirect_uri=${urlencode(this.location)}/&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect`
  } 
}

我这里进入页面没有openid都获取openid所以放在了(permission.js)路由守卫里面写

import { WX_CONFIG } from '@/config/defaultSettings' //(记得引入文件)
router.beforeEach((to, from, next) => {
  NProgress.start() // start progress bar

  // 路由发生变化修改页面title
  if (to.meta.title) {
    document.title = to.meta.title
  }
  // 获取路由query参数
  store.commit('user/SetUrlQuery', to.query)

  //404通过,有openId通过
  if (to.name == '404' || Vue.ls.get('openid')) {
    next()
    //没有openid则去获取
  } else if (!Vue.ls.get('openid')) {
    // 有code调用接口
    if (to.query.code) {
      store.dispatch('user/GetOpenId', to.query.code).then(res => {
        if (res.errcode) {
          WX_CONFIG.redirect()
        }
        // 设置openid
        Vue.ls.set('openid', res.openid)
        // next({name:to.name})
        next()
      }).catch(err => { 
        WX_CONFIG.redirect()
        console.log(err)
      })
      // 否则重定向页面
    }else{
      WX_CONFIG.redirect()
    }
  }
})

在user.js文件中在这里插入图片描述

const user = {
  namespaced: true,
  state: {
    code:'',
    unitId: '',
    urlQuery:{},
    userInfo: {
      openId: '',
      phoneNbr:'',
      name:'',
    }
  },
  mutations: {
    setUserInfo (state, info) {
      vm.$ls.set('userInfo',JSON.stringify(info))
      state.userInfo = JSON.parse(JSON.stringify(info))
      state.unitId = state.userInfo.unitId
    },
       // 设置Url参数
    SetUrlQuery(state, info) {
      state.urlQuery = Object.assign(JSON.parse(Vue.ls.get('urlQuery')) || {},info)
      Vue.ls.set('urlQuery', JSON.stringify(state.urlQuery))
    },
  },
  actions: {
    //获取openid
    GetOpenId(state,code) {
      return new Promise((resolve, reject) => {
        util.http({
          baseURL:'',
          url: 'wxapi/sns/oauth2/access_token',
          method: 'get',
          params: {
            code,
            grant_type:'authorization_code',
            secret:WX_CONFIG.appsecret,
            appid:WX_CONFIG.appid,
          }
        }).then(res => {
          resolve(res)
        }).catch((err) => {
          reject(err)
        })
      })
    },
        // 获取用户信息
        GetInfo ({ commit }, token) {
          return new Promise((resolve, reject) => {
            getUser(token).then(res => {
              commit('setUserInfo', { ...res.data, phoneNbr: res.data.phone })
              resolve(JSON.parse(JSON.stringify(res)))
            }).catch((err) => {
              reject(err)
            })
          })
        },
  }
}

export default user

打包到线上的话需要配置代理(第一次做这个的时候就是不知道要配置代理,我本地测试都很正常打包到线上http404)

  devServer: {
    proxy: {
      '/green/wxapi': {// 微信接口跨域(我这边指向的路径文件名是green)
        'target': 'https://api.weixin.qq.com', 
        'secure': true, // false为http访问,true为https访问
        'changeOrigin': true, // 跨域访问设置,true代表跨域
        'pathRewrite': { // 路径改写规则
          '^/green/wxapi': ''
        }
      }
    }
  }

前端配置完代理后记得tomcat也需要对应配置(记得清理缓存重启,确定前端没错的情况下在postman测试还是没转过去的话,让配置tomcat的小伙伴看看是不是入口路径啥的是不是不止一个,导致没指向到正确的地址,说多了都是泪!!!!)history模式基本就是这样了

location ^~ /green/wxapi/ {
        proxy_pass https://api.weixin.qq.com/;
        # proxy_redirect off;
        # proxy_set_header X-Real-IP $remote_addr;
        # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # proxy_set_header Host $host;
        # proxy_set_header X-Forwarded-proto https;
    }

2.hash模式
在config文件夹下定义一个js文件方便使用(例如:defaultSettings.js)同history模式
我这里进入页面没有openid都获取openid所以放在了(permission.js)路由守卫里面写
hash模式下运行程序会自动改变url的顺序code会接在域名后(例如:http://xxxxx.xxxx.cn/green/?code=0714Fy0w3AIujZ2cdB2w3dK04G04Fy0X&state=STATE#/passCertixxxx?unitId=010069xxxxxxx)其实原来的路径还有别参数然后别的参数就接在最后了

import { WX_CONFIG } from '@/config/defaultSettings' // 引入
router.beforeEach((to, from, next) => {
  NProgress.start() // start progress bar
  if (to.meta.title) {// 路由发生变化修改页面title 
    document.title = to.meta.title
  } 
 // 第一反应是把路径变为正常的(如下,但是后续成功后会报40029或者40163错误码表示code被使用过了,打断点明明就调用了一次也是很懵,没想到拿是否存在code当条件这都不行,然后把下面这段注掉就好了,这也行????最后就是路径还是乱的,但是获取code就行)
  // if (window.location.href.indexOf('visitor/?code') != -1) {
  //   const url = window.location.href.split('')
  //   const right = url.splice(url.indexOf('#')).join('')
  //   url.splice(url.indexOf('?'), 0, right)
  //   window.location.href = url.join('')
  // }
    // 获取路由query参数
 // store.commit('user/SetUrlQuery', to.query)
// 获取url中的参数 hash模式下
function getPathObj (str) {
  return str.indexOf('?code=') == -1 ? false : str.substr(str.indexOf('?code=')+6,32)
  }
  const code = getPathObj(window.location.href);
    //404通过,有openId通过
    if (to.name == '404' || Vue.ls.get('openid')) {
      next()
      //没有openid则去获取
    } else if (!Vue.ls.get('openid')) {
      // 有code调用接口
      if (code) {
        store.dispatch('user/GetOpenId', code).then(res => {
          // console.log('res: ', res);
          if (res.errcode) {
            WX_CONFIG.redirect()
          }
          console.log('openid------', res.openid);
          // alert(res.openid)
          // 设置openid
          Vue.ls.set('openid', res.openid)
          store.state.user.userInfo.openId = res.openid
          // next({name:to.name})
          next()
        }).catch(err => { 
          WX_CONFIG.redirect()
          console.log(err)
        })
        // 否则重定向页面
      } else {
        WX_CONFIG.redirect()
      }
    }
})

其他,同history模式

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值