1、微信公众号获取授权
出现的坑:只做授权之后微信公众号一直在回调微信接口,导致有很多的code,需要判断是否有code值出现
完整代码:
<template>
<RouterView />
</template>
<script setup>
import { onBeforeMount } from 'vue';
import $api from '@/api/index.js';
const APPID='wx000000000111000';
async function getOpen() {
const local = window.location.href;
sessionStorage.setItem('local', local)//这个地方存用户点击过来的地方方便做重定向处理
let url =
'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + APPID + '&redirect_uri=' + encodeURIComponent(local) + '&response_type=code&scope=snsapi_userinfo&state=1&connect_redirect=1#wechat_redirect'
if (window.location.href.indexOf('code=') != -1) { // 避免一直重复重定向无限获取code
let code = await getUrlName('code') // 从url中获取code的值
if (code == sessionStorage.getItem('code')) { // 微信获取code会重定向,所以从别的页面返回本页后,返回的其实是重定向之后的url,此时url一定带有上次的code,code只能用一次,这时候要重新获取
let urls = await deUrlParam(window.location.href, ['code']) // 从url中删除code
window.location.href = urls
}
sessionStorage.setItem('code', code)
} else {
window.location.href = url
}
}
//从url中获取指定参数的值
const getUrlName=(paramName)=> {
const url = window.location.href;
const regex = new RegExp(`${paramName}=([^&]*)`);
const match = regex.exec(url);
if (match) {
return match[1];
} else {
return null;
}
}
//删除URL中指定search参数,会将参数值一起删除,返回没有该参数的完整url
const deUrlParam=(url, params)=> {
/**
* 删除URL中指定search参数,会将参数值一起删除
* @param {string} url 地址字符串
* @param {array} aParam 要删除的参数key数组,如['name','age']
* @return {string} 返回新URL字符串
*/
for (var index = 0; index < params.length; index++) {
var item = params[index];
var fromIndex = url.indexOf(item + "="); //必须加=号,避免参数值中包含item字符串
if (fromIndex !== -1) {
// 通过url特殊符号,计算出=号后面的的字符数,用于生成replace正则
var startIndex = url.indexOf("=", fromIndex);
var endIndex = url.indexOf("&", fromIndex);
var hashIndex = url.indexOf("#", fromIndex);
var reg = "";
if (endIndex !== -1) {
// 后面还有search参数的情况
var num = endIndex - startIndex;
reg = new RegExp(item + "=.{" + num + "}");
url = url.replace(reg, "");
} else if (hashIndex !== -1) {
// 有hash参数的情况
var num = hashIndex - startIndex - 1;
reg = new RegExp("&?" + item + "=.{" + num + "}");
url = url.replace(reg, "");
} else {
// search参数在最后或只有一个参数的情况
reg = new RegExp("&?" + item + "=.+");
url = url.replace(reg, "");
}
}
}
var noSearchParam = url.indexOf("=");
if (noSearchParam === -1) {
url = url.replace(/\?/, ""); // 如果已经没有参数,删除?号
}
return url;
}
getOpen()
</script>
<style lang="scss" scoped>
</style>
2、项目上线了一段时间发现一个新bug,有的人拿不到openid,找了好久的原因,最后找到一个方案。
2.1、openid拿不到是因为code请求了多次,至于原因嘛,我估计是页面可能多次请求了,但是在调试过程中只请求了一次。
还发现在拿到回调的链接时会一直在这个地方,如果多次刷新会多次请求,所以解决这个问题就ok了
window.location.href='http://你的链接.html'
授权之后拿到openid重新定义一下地址栏,清理干净之后就正常了
2、重定向处理
注:在通过接口拿到openid之后需要跳转页面可从之前存的缓存里面获取,然后在定义跳转的时候重新定义跳转路由
const getOpenId = (code)=>{//获取openid
$api.getCallbackOpenid({code:code}).then(res=>{
if(res.code===0){
let user=JSON.parse(res.data);
if(user) if(user.openid){
let pathSess=sessionStorage.getItem('local');
if(pathSess){
if(pathSess.split('#').length>1){
//不是所有页面都有#,这个地方是因为我的路由模式是createWebHashHistory这个要注意,不是这个模式的判断需要根据你的url去做处理
let path=pathSess.split('#')[1];
sessionStorage.setItem('path',path);
window.location.href=`http://xxx.com/index.html#${path}`;
}
}else{
window.location.href='http://xxx.com/index.html'
}
}
}
})
}