vue-cli项目。路由是hash模式。须要受权的场景有:项目入口处(App.vue),指定页面(建立时、methods 方法内);能够携带参数vue
因为hash模式# 号的存在,受权后连接会被扰乱。因此 我但愿在 受权前 将重定向的连接 即 redirect_uri 改成没有# 的url。而后在 项目入口处 进行 url 重置,将其改回到 丑陋的 带#连接。vue-cli
即:两步操做api
一、受权前 将redirect_uri 改成没有# 的url微信
二、项目入口处,将没有#的url改回到 带#的url,跳到指定页面。app
这里会将当前页面的原有参数信息、额外参数、codepath参数 做为 redirect_uri 的新参数。其中codepath是 用来指定 跳转页面的,一般为 受权发起页。url
/** * 开始设置页面连接,进行code 受权重定向 * * @param scope 受权做用域 * @param path 受权所在页面 path * @param extraPm 额外参数,须要在 配置中 进行参数配置 * @returns {string} */ get_codeV3(scope, path, extraPm={}) { if (process.env.NODE_ENV === 'development' && config.isMockWeChat) return '0713eFVW0AmFP12kGVTW0oGDVW03eFV2' let homeUrl = '', searchOb = {}, searchstr = '' let oriUrls = window.location.href.split('?') let baseShareURl = window.location.origin + window.location.pathname homeUrl = baseShareURl if (oriUrls.length > 1) { let searchUrls = oriUrls[1].split('#') let searchUrlReal = searchUrls[0] searchOb = qs.parse(searchUrlReal) let {code} = searchOb if (code) delete searchOb.code } searchOb.codepath = path Object.assign(searchOb, extraPm) searchstr = `?${qs.stringify(searchOb)}` homeUrl += searchstr let redirect_uri = encodeURIComponent(homeUrl); let response_type = 'code'; // 应用受权做用域, // snsapi_base (不弹出受权页面,直接跳转,只能获取用户openid), // snsapi_userinfo (弹出受权页面,可经过openid拿到昵称、性别、所在地。而且, 即便在未关注的状况下,只要用户受权,也能获取其信息 ) // 重定向后会带上state参数,开发者能够填写a-zA-Z0-9的参数值,最多128字节 let state = ''; let url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=${response_type}&scope=${scope}&state=${state}#wechat_redirect`; window.location.href = url; }
在项目入口处,发现有 codepath 参数,即 将该连接视为 受权后的redirect_uri 连接。进行页面重定向,跳转到 codepath 指定页面spa
/** * 页面重定向(受权)-确保页面连接正常 * 支持多参、无参、指定页面
* code 在 返回的search 里 * @returns {{needRedirect: boolean, homeUrl: string, search: {}}} */ urlResetForWxCode: function () { //须要重定向时:codepath 参数 与 code 参数同在。 let needRedirect = false, homeUrl = '', searchOb = {}, searchstr = '' let oriUrls = window.location.href.split('?') let baseShareURl = window.location.origin + window.location.pathname homeUrl = baseShareURl if (oriUrls.length > 1) { let searchUrls = oriUrls[1].split('#') let searchUrlReal = searchUrls[0] let searchObReal = {} searchOb = qs.parse(searchUrlReal) let { codepath } = searchOb needRedirect = codepath if (codepath) { config.platform.wxCode[codepath].forEach(item => searchObReal[item] = searchOb[item]) if (config.platform.wxCode[codepath].length) searchstr = `?${qs.stringify(searchObReal)}` homeUrl += `#${codepath}` + (searchstr.length > 1 ? searchstr : '') } } return { needRedirect, homeUrl, search: searchOb } }
// 配置信息localstorage
config = { platform: { wxCode: {'/': ['hello', 'yiha'], '/spe': ['spp']}, // 微信受权-须要受权的页面: [页面用到的参数]
}
}
if (!storage.getToken()) {// code 受权标志 保存在localstorage。 wx_jssdk.get_codeV3('snsapi_userinfo', '/') return }
// App.vuecode
created(){ // 能够在项目入口处 进行code受权 if (!storage.getToken()) {// code 受权标志 保存在localstorage。 wx_jssdk.get_codeV3('snsapi_userinfo', '/') return } // 项目只要用到受权,则须要进行重定向判断。 let {needRedirect, homeUrl, search} = browserUtil.urlResetForWxCode() if (needRedirect) { storage.setToken({code: search.code}) // 保存code window.location.href = homeUrl } }
想着尽可能可以作到配置化、可扩展,目前很low。凑合用吧😄orm
连接前置判断方法内,组装连接参数时,我是只拿配置信息里的存在的参数。(方法里飘红的代码)。这是为了参数可控,避免没必要要的bug。
在redirect_uri 重置方法 参数里,有一个额外参数,本来 想着只截取受权发起页的原始search参数就行了。但一想 会不会有这样的使用场景:
表单提交页,在提交时 才去发起受权。这样的话 可能受权后 原表单信息已丢失,即须要从新再来;体验并很差。那么可不能够 将表单数据做为 受权时的一部分参数,而后在受权成功后,页面从新create时 检测到有表单数据时 直接提交。(固然,你也能够经过local保存数据来实现这个功能,或者其余)
注:该额外参数 也须要在配置里注明,否则 前置判断里 会不予理会。