微信内网页
微信内开发网页的注意事项
1.登录
我们要在微信内开发网页,那肯定是需要用到微信登录获取到用户唯一标识符。这就要用到微信提供的网页授权,官方文档步骤写的比较清晰:网页授权官方文档 ,在这里说几点我在项目中使用的方法,因为网页授权是需要跳转到另一个网页,用户点授权后返回的url带回code参数,因此我们需要根据具体的业务需求来确定方法,是必须要登录才能进行操作还是在关键操作下再进行登录。
这里我是采用用户进入就必须登录的方案,首先根据用户本地是否存储过urserinfo,其次判断token是否过期也就是返回值是不是401,如果两者有一个不符合就调用登录方法:
const wxCode = async () => {
const callbackURL = encodeURIComponent("https://XXXXXX");
const redirectURI = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${wechatId}&redirect_uri=${callbackURL}&response_type=code&connect_redirect=1&scope=snsapi_userinfo&state=1#wechat_redirect`;
window.location.href = redirectURI;
};
appid、redirect_uri这些文档上都有说明,当用户同意授权后,会跳转到callbackURL,并且后面携带code参数,这时我们只要在页面进入时判断url是否有code参数,如果有则执行登录操作
const hasCode = async () => {
const currentURL = new URL(window.location.href);
const params = new URLSearchParams(currentURL.search);
if (params.has("code")) {
code.value = params.get("code"); // 这里拿到code
await login(code.value);
}
};
这个函数放在onMounted周期中执行
2.分享
我们一般希望用户分享出去的内容是我们能控制的,用户点击链接进入我们预想的页面,这里链接地址必须在公众号设置里的JS接口安全域名中进行配置。
这里我使用了weixin-js-sdk库,JS—SDK可以看文档说明:官方文档
// 在组件加载时初始化微信JS-SDK
async function initWechatJS() {
const wechatConfig = await getWechatConfig(); // 后端获取微信配置信息
wx.config({
debug: false, // 是否开启调试模式,调试模式下会输出调试信息
appId: 'wx000000000000', // 微信公众号的唯一标识
timestamp: wechatConfig.timestamp, // 生成签名的时间戳
nonceStr: wechatConfig.nonceStr, // 生成签名的随机串
signature: wechatConfig.signature, // 签名
jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline'] // 需要使用的JS接口列表
})
wx.ready(function () {
const title = 'XXXXX'
const link = 'https://XXXXXXXX'
const imgUrl = ''
wx.onMenuShareAppMessage({
title,
link,
imgUrl,
success: async function () {
// 成功操作
}
})
wx.onMenuShareTimeline({
title,
link,
imgUrl,
success: async function () {
...
}
})
})
}
initWechatJS()
// 调用后端接口获取微信配置信息
async function getWechatConfig() {
const currentURL = new URL(window.location.href);
// 发送请求获取微信配置信息,将当前页面的URL作为参数传递给后端
const response = await getWxAuth(currentURL);
const data = response.data;
return data;
}
wechatConfig里面的数据都是由后端返回,JS-SDK里面有详细说明
微信小程序
3.接口401自动登录
我们公司项目为了用户体验设计成自动登录,token又只有一个时效也很短,于是乎我们只能在前端上处理一下啦,在响应拦截里面对401做处理,设计一个队列,并在登录操作时候加锁,当处理完401登录操作之后,对队列中的请求进行再次发送。
这样相当于响应的还是用户之前的操作,让用户能无感登录。具体代码贴下面:
// 使用一个变量来表示是否正在进行登录操作
let isLoggingIn = false
// 用于等待登录完成的队列
const loginQueue = []
// 请求拦截
http.interceptors.request.use(async (config) => {
if (config.url) {
if (isLoggingIn && config.url !== '/login') {
return new Promise((resolve) => {
loginQueue.push(() => {
resolve(config)
})
})
}
...
return config
} else {
http.abort()
}
})
// 响应拦截
http.interceptors.response.use(async (response) => {
const code = response.data.code || 200;
try {
if (code === 401) {
// 如果没有在进行登录操作,则执行登录操作
if (!isLoggingIn) {
isLoggingIn = true
await login()
isLoggingIn = false
// 登录完成后执行等待队列中的请求
while (loginQueue.length > 0) {
const nextRequest = loginQueue.shift()
nextRequest && await http.request(nextRequest())
}
} else {
return new Promise((resolve) => {
loginQueue.push(() => {
resolve(http.request(response.config))
})
})
}
return http.request(response.config)
} else {
return response ? response.data : {}
}
} catch (error) {
...
}
}, (error) => {
...
})
这样的处理方案其实不好,还是用双token为妙!