diff --git a/wx-auth.js b/wx-auth.js new file mode 100644 index 0000000..9b20665 --- /dev/null +++ b/wx-auth.js @@ -0,0 +1,108 @@ +/* ============================================================ + wx-auth.js · H5 应用通用授权 + 跳商城 共享助手(各 H5 应用引用即可) + ------------------------------------------------------------ + 依赖:页面引入 + 用法:在 H5 页面里 + + 然后: + wxAuth.init(); // 检测环境 + 读取已授权资料(hash) + 回填 + wxAuth.isAuthorized(); // 是否已授权(手机号/昵称/头像任一非空) + wxAuth.requestProfile(); // 点「授权登录」→ postMessage 通知宿主页 + wxAuth.goMall(); // 点「进商城」→ 跳小程序商城 tabBar 页 + 回传协议:宿主页授权成功后更新 web-view src 为 + ?t=#openid=..&phone=..&nickname=..&avatar=.. + (微信 webview 丢 query、不丢 hash,故授权结果放 hash) + ============================================================ */ +(function (g) { + 'use strict'; + function readHash(name) { + try { + var h = location.hash.slice(1) + '&' + location.search.slice(1); + var m = h.match(new RegExp('(?:^|[&#])' + name + '=([^&#]*)(?:$|[&#])')); + return m ? decodeURIComponent(m[1]) : ''; + } catch (e) { return ''; } + } + var wxAuth = { + MODE: 'browser', // 'webview' | 'wechat-browser' | 'browser' + inWebview: false, + onReady: null, + /* ① 环境检测 + 读回传资料(授权后宿主更新 src,本页重载读到 hash) */ + init: function (cb) { + this.onReady = cb || null; + var self = this; + var isWechat = /MicroMessenger/i.test(navigator.userAgent); + function setMode(m) { + self.MODE = m; self.inWebview = (m === 'webview'); + if (self.onReady) self.onReady(self); + } + if (window.wx && window.wx.miniProgram) { + var responded = false; + window.wx.miniProgram.getEnv(function (r) { + responded = true; + setMode(r && r.miniprogram ? 'webview' : (isWechat ? 'wechat-browser' : 'browser')); + }); + setTimeout(function () { if (!responded) setMode(isWechat ? 'wechat-browser' : 'browser'); }, 800); + } else { + setMode(isWechat ? 'wechat-browser' : 'browser'); + } + }, + /* ② 读取授权结果(hash 里的 phone/nickname/avatar) */ + readAuth: function () { + return { phone: readHash('phone'), nickname: readHash('nickname'), avatar: readHash('avatar') }; + }, + /* ③ 是否已授权 */ + isAuthorized: function () { + var a = this.readAuth(); + return !!(a.nickname || a.avatar || a.phone); + }, + /* ④ 请求授权:navigateTo → 小程序端独立授权页(默认 pages/annex/auth/index)。 + 改动说明:微信 web-view 的 postMessage 非实时送达,点击时端上收不到; + 改用 wx.miniProgram.navigateTo 实时跳转到授权页,避开该限制。 */ + /* ④ 请求授权:环境判定(与 goMall/mama-box 同一套): + ① UA 不含 MicroMessenger = 普通浏览器 → 直接提示(秒出,不等超时); + ② 微信内 → getEnv 确认是否 webview(纯浏览器加载了 jweixin 时 getEnv + 不回调,800ms 超时兜底)→ 是小程序才 navigateTo 授权页。 */ + requestProfile: function (authPage) { + var self = this; + function nav() { + window.wx.miniProgram.navigateTo({ url: authPage || '/pages/annex/auth/index' }); + self.toast('正在打开授权页…'); + } + if (!/MicroMessenger/i.test(navigator.userAgent)) { + this.toast('请在小程序中完成授权登录'); + return; + } + if (window.wx && window.wx.miniProgram) { + var responded = false; + window.wx.miniProgram.getEnv(function (r) { + responded = true; + if (r && r.miniprogram) nav(); + else self.toast('请在小程序中完成授权登录'); + }); + setTimeout(function () { + if (!responded) self.toast('请在小程序中完成授权登录'); + }, 800); + } else { + this.toast('请在小程序中完成授权登录'); + } + }, + /* ⑤ 跳小程序商城(tabBar 页用 switchTab;非 tabBar 用 navigateTo) */ + goMall: function (url) { + if (!(window.wx && window.wx.miniProgram)) { this.toast('请在微信小程序中打开商城'); return; } + window.wx.miniProgram.switchTab({ url: url || '/pages/goods_cate/goods_cate' }); + }, + /* ⑥ 展示授权结果到指定元素(可选便捷方法) */ + fillAuth: function (nameEl, avatarEl) { + var a = this.readAuth(); + if (nameEl && a.nickname) nameEl.textContent = a.nickname; + if (avatarEl && a.avatar) avatarEl.src = a.avatar; + }, + toast: function (m) { + var t = document.getElementById('toast'); + if (!t) return; + t.textContent = m; t.classList.add('show'); + clearTimeout(t._tt); t._tt = setTimeout(function () { t.classList.remove('show'); }, 1800); + } + }; + g.wxAuth = wxAuth; +})(window);