122 lines
8.0 KiB
HTML
122 lines
8.0 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
|
||
<meta name="theme-color" content="#F4593C">
|
||
<title>wx-h5-demo · 小程序授权演示(独立项目)</title>
|
||
<style>
|
||
* { margin:0; padding:0; box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
|
||
body { font-family:-apple-system,"PingFang SC","Microsoft YaHei",sans-serif; background:#F8F3EF; color:#2B2320; min-height:100vh; display:flex; justify-content:center; }
|
||
.wrap { width:100%; max-width:430px; padding:24px 20px 40px; }
|
||
.brand { font-size:22px; font-weight:800; color:#F4593C; } .brand small{color:#A79C95;font-size:13px;font-weight:500;margin-left:8px}
|
||
.env { margin:14px 0 8px; font-size:13px; color:#6B615B; } .env b{color:#2B2320}
|
||
.tag { display:inline-block; padding:2px 8px; border-radius:8px; font-size:12px; }
|
||
.tag.s0{background:#E8F2EB;color:#5F8A4A} .tag.s1{background:#FDEEDD;color:#B8860B} .tag.s2{background:#F6DCD6;color:#C4553A}
|
||
.card { background:#fff; border:1px solid #EFE7E1; border-radius:16px; padding:16px; margin-top:14px; }
|
||
.card h2{font-size:15px;font-weight:800;margin-bottom:10px}
|
||
.row{display:flex;justify-content:space-between;align-items:center;padding:10px 0;border-bottom:1px dashed #EFE7E1;font-size:14px}
|
||
.row:last-child{border-bottom:none} .row .k{color:#6B615B} .row .v{font-weight:600} .row .v.placeholder{color:#C9B7AC;font-weight:500}
|
||
.avatar{width:44px;height:44px;border-radius:50%;background:#F1E6E0;overflow:hidden;display:flex;align-items:center;justify-content:center;font-size:18px}
|
||
.avatar img{width:100%;height:100%;object-fit:cover}
|
||
.btn{display:block;width:100%;padding:15px;border:none;border-radius:14px;font-size:15px;font-weight:700;margin-top:14px;cursor:pointer}
|
||
.btn.main{background:#F4593C;color:#fff} .btn.ghost{background:#fff;color:#6B615B;border:1px solid #EFE7E1}
|
||
.hint{font-size:12px;color:#A79C95;margin-top:12px;line-height:1.6}
|
||
#toast{position:fixed;left:50%;bottom:14%;transform:translateX(-50%);background:rgba(30,22,18,.9);color:#fff;padding:10px 18px;border-radius:10px;font-size:13px;opacity:0;pointer-events:none;transition:opacity .25s;z-index:99}
|
||
#toast.show{opacity:1}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="wrap">
|
||
<div class="brand">wx-h5-demo <small>独立示例 · 小程序授权</small></div>
|
||
<div class="env">场景:<b id="envTxt">检测中…</b> <span id="envTag" class="tag s2">纯浏览器</span></div>
|
||
|
||
<div class="card">
|
||
<h2>当前可用的授权方式</h2>
|
||
<p id="scenarioTxt" style="font-size:13px;color:#6B615B;line-height:1.6">检测环境后,这里会给出「场景1 或 场景2」对应的授权入口。</p>
|
||
<button class="btn main" id="btnJump">去小程序授权</button>
|
||
<button class="btn ghost" id="btnPost">在 web-view 里请求授权(postMessage)</button>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2>授权结果(小程序回传后读取)</h2>
|
||
<div class="row"><span class="k">手机号</span><span class="v placeholder" id="rPhone">—</span></div>
|
||
<div class="row"><span class="k">昵称</span><span class="v placeholder" id="rNick">—</span></div>
|
||
<div class="row"><span class="k">头像</span><span class="v"><span class="avatar" id="rAvatarWrap"><span id="rAvatarText">宝</span></span></span></div>
|
||
</div>
|
||
|
||
<p class="hint">
|
||
场景1(微信浏览器打开 H5):点「去小程序授权」→ 经 <code>wx-open-launch-weapp</code> / 小程序 <code>URL Scheme</code> 跳进小程序授权页 → 授权后,小程序用 <code>web-view</code> 加载本 H5(结果在 URL),即「回到 H5」。
|
||
场景2(web-view 里的 H5):点「在 web-view 里请求授权」→ <code>postMessage</code> → 宿主小程序弹原生授权面板 → 更新 <code>web-view src</code>(带 #phone/nickname/avatar)→ 本页重载显示。
|
||
完整说明见 <code>docs/h5-miniprogram-auth.md</code>;小程序端配套代码见本目录 <code>miniapp/</code>。
|
||
</p>
|
||
</div>
|
||
<div id="toast"></div>
|
||
|
||
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
|
||
<script>
|
||
(function () {
|
||
'use strict';
|
||
function $(s) { return document.querySelector(s); }
|
||
function toast(msg) { var t=$('#toast'); t.textContent=msg; t.classList.add('show'); clearTimeout(t._t); t._t=setTimeout(function(){t.classList.remove('show');},1800); }
|
||
function readParam(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 MODE = ''; // 'webview' | 'wechat-browser' | 'browser'
|
||
var isWechat = /MicroMessenger/i.test(navigator.userAgent);
|
||
var inWebview = false;
|
||
|
||
function setEnv(mode, label, cls) {
|
||
MODE = mode; inWebview = (mode === 'webview');
|
||
$('#envTxt').textContent = label; $('#envTag').textContent = label; $('#envTag').className = 'tag ' + cls;
|
||
var txt = '';
|
||
if (mode === 'webview') txt = '场景2:本页运行在小程序 web-view 里。点下方「在 web-view 里请求授权」→ postMessage 通知宿主小程序弹原生授权面板;授权后宿主更新 web-view src 回传,本页重载显示结果。';
|
||
else if (mode === 'wechat-browser') txt = '场景1:本页在微信浏览器打开(非 web-view)。点「去小程序授权」→ 跳进小程序授权页授权;授权后小程序用 web-view 加载本 H5(结果在 URL)即回到 H5。';
|
||
else txt = '纯浏览器:仅演示 UI,无法真授权(去小程序按钮/场景2需在微信内)。';
|
||
$('#scenarioTxt').textContent = txt;
|
||
}
|
||
|
||
function detectEnv() {
|
||
if (window.wx && window.wx.miniProgram) {
|
||
var responded = false;
|
||
window.wx.miniProgram.getEnv(function (r) { responded = true; setEnv(r && r.miniprogram ? 'webview' : (isWechat ? 'wechat-browser' : 'browser'), r && r.miniprogram ? '小程序 web-view' : (isWechat ? '微信浏览器' : '纯浏览器'), r && r.miniprogram ? 's0' : (isWechat ? 's1' : 's2')); });
|
||
setTimeout(function () { if (!responded) setEnv(isWechat ? 'wechat-browser' : 'browser', isWechat ? '微信浏览器' : '纯浏览器', isWechat ? 's1' : 's2'); }, 800);
|
||
} else {
|
||
setEnv(isWechat ? 'wechat-browser' : 'browser', isWechat ? '微信浏览器' : '纯浏览器', isWechat ? 's1' : 's2');
|
||
}
|
||
}
|
||
|
||
// 场景1:跳小程序授权(wx-open-launch-weapp 或 URL Scheme) → 小程序授权页
|
||
function jumpToMiniAuth() {
|
||
if (MODE === 'browser') { toast('请在微信内打开'); return; }
|
||
// 方式A:公众号/网页 JSSDK `<wx-open-launch-weapp>`(需 jsapi 签名 + 微信内打开)
|
||
// 方式B:小程序 URL Scheme(后端用 appid+path 换 scheme,形如 weixin://dl/business/?t=xxx)
|
||
var scheme = $('#launchPath') && $('#launchPath').value; // 你可在下面填 scheme 或 path
|
||
if (scheme) { location.href = scheme; return; }
|
||
toast('请在此填入小程序授权页的 scheme/launch 入口(见 README)');
|
||
}
|
||
|
||
// 场景2:postMessage 请求 web-view 宿主弹授权面板
|
||
function requestAuthInWebview() {
|
||
if (MODE !== 'webview') { toast('仅 web-view 环境可用(场景2)'); return; }
|
||
window.wx.miniProgram.postMessage({ data: { action: 'requestProfile' } });
|
||
toast('请在弹出的小程序面板授权');
|
||
}
|
||
|
||
function renderResult() {
|
||
var phone = readParam('phone'), nick = readParam('nickname'), avatar = readParam('avatar'), authed = readParam('authed');
|
||
if (phone) { $('#rPhone').textContent = phone; $('#rPhone').classList.remove('placeholder'); }
|
||
if (nick) { $('#rNick').textContent = nick; $('#rNick').classList.remove('placeholder'); }
|
||
if (avatar){ $('#rAvatarWrap').innerHTML = '<img src="' + avatar + '" alt="头像">'; }
|
||
if (authed) toast('授权完成,已回传');
|
||
}
|
||
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
detectEnv(); renderResult();
|
||
$('#btnJump').addEventListener('click', jumpToMiniAuth);
|
||
$('#btnPost').addEventListener('click', requestAuthInWebview);
|
||
});
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|