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保存數據來實現這個功能,或者其餘)
注:該額外參數 也須要在配置裏註明,否則 前置判斷裏 會不予理會。