Files
wx-h5-demo/index.html

127 lines
8.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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) → 小程序授权页
var LAUNCH_PATH = '/pages/demo/auth'; // 小程序授权页路径(场景1 的授权页,见 miniapp/scenario1-auth-bridge.*)
var LAUNCH_SCHEME = ''; // 微信浏览器用的 URL Scheme(后端用 appid+path 生成,见 README);留空则走 webview navigateTo
function jumpToMiniAuth() {
if (MODE === 'browser') { toast('请在微信内打开'); return; }
// 小程序 web-view 内:用 wx.miniProgram.navigateTo 跳到授权页(场景1 在 webview 里的做法)
if (window.wx && window.wx.miniProgram && inWebview) {
window.wx.miniProgram.navigateTo({ url: LAUNCH_PATH });
return;
}
// 微信浏览器(非 web-view):优先 URL Scheme;否则提示用 <wx-open-launch-weapp>(需 jsapi 签名)
if (LAUNCH_SCHEME) { location.href = LAUNCH_SCHEME; return; }
toast('请配置小程序 URL Scheme(后端生成)或用 <wx-open-launch-weapp> 跳授权页');
}
// 场景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>