Przeglądaj źródła

微信内打开app

zhuli 2 tygodni temu
rodzic
commit
e5052cf4b5
1 zmienionych plików z 93 dodań i 23 usunięć
  1. 93 23
      HBuilderProjects/shareIndex.html

+ 93 - 23
HBuilderProjects/shareIndex.html

@@ -1076,6 +1076,8 @@
 		var weChatJssdkConfigured = false;
 		var wxConfigSignRetriedBaseUrl = false;
 		var wxSignUrlFullBeforeStrip = '';
+		var wxInitLastError = '';
+		var wxJssdkInitPromise = null;
 
 		/**
 		 * 关店(businessStatus=99)更多推荐:POST …/ai/multimodal-services/api/v1/search/global/store-recommend
@@ -1291,9 +1293,15 @@
 			return deep.length <= 1024 ? deep : (pageUrl || deep).slice(0, 1024);
 		}
 
+		function setWxInitError(msg) {
+			wxInitLastError = String(msg || '').trim();
+			if (wxInitLastError) console.warn('[wx]', wxInitLastError);
+		}
+
 		function fetchWeChatJssdkSign(signPageUrl) {
 			signPageUrl = signPageUrl || getWxConfigSignUrl();
 			var url = buildWxGetConfigRequestUrl(signPageUrl);
+			console.log('[wx] GET getWxConfig →', url);
 			return fetch(url, {
 				method: 'GET',
 				mode: 'cors',
@@ -1301,18 +1309,32 @@
 				headers: { Accept: 'application/json' }
 			})
 				.then(function (r) {
-					if (!r.ok) throw new Error('HTTP ' + r.status);
-					return r.json();
+					if (r.ok) return r.json();
+					return r
+						.text()
+						.catch(function () {
+							return '';
+						})
+						.then(function (text) {
+							var hint = '';
+							try {
+								var j = JSON.parse(text);
+								hint = j.msg || j.message || '';
+							} catch (eP) {
+								if (text) hint = text.slice(0, 120);
+							}
+							throw new Error('getWxConfig HTTP ' + r.status + (hint ? ':' + hint : ''));
+						});
 				})
 				.then(function (res) {
 					if (res && res.code != null) {
 						var c = Number(res.code);
 						if (c !== 200 && c !== 0 && res.success !== true) {
-							throw new Error(res.msg || 'sign rejected');
+							throw new Error(res.msg || res.message || 'getWxConfig code ' + c);
 						}
 					}
 					var pack = normalizeWxJssdkSignPayload(res, signPageUrl);
-					if (!pack) throw new Error('empty sign');
+					if (!pack) throw new Error('getWxConfig 缺少 appId/timestamp/nonceStr/signature');
 					return pack;
 				});
 		}
@@ -1348,9 +1370,11 @@
 				});
 				wx.error(function (err) {
 					weChatJssdkConfigured = false;
+					wxJssdkInitPromise = null;
 					updateFabOpenLayer();
 					var errMsg = getWxErrMsg(err);
-					if (isWxDebugOn()) window.alert(formatWxConfigErrorTip(err, urlForWx));
+					setWxInitError(formatWxConfigErrorTip(err, urlForWx));
+					if (isWxDebugOn()) window.alert(wxInitLastError);
 					console.warn('[wx.config]', errMsg, urlForWx);
 					var baseUrl = getWxSignUrlBase();
 					var fullUrl = getWxSignUrlFull();
@@ -1438,35 +1462,82 @@
 		}
 
 		function initWeChatOpenLaunchApp() {
-			if (!isWeChatInAppBrowser()) return Promise.resolve(false);
+			if (!isWeChatInAppBrowser()) {
+				console.log('[wx] 未调用 getWxConfig:当前不是微信内置浏览器');
+				return Promise.resolve(false);
+			}
+			if (wxJssdkInitPromise) return wxJssdkInitPromise;
+
 			wxConfigSignRetriedBaseUrl = false;
+			wxInitLastError = '';
 			var signPageUrl = getWxConfigSignUrl();
+
 			if (typeof wx === 'undefined') {
-				console.warn('[wx] jweixin not loaded');
+				setWxInitError('jweixin.js 未加载,无法请求 getWxConfig');
+				console.warn('[wx] 未调用 getWxConfig:wx 对象不存在');
 				return Promise.resolve(false);
 			}
+
 			bindWeChatLaunchTagEvents();
-			return fetchWeChatJssdkSign(signPageUrl)
+			wxJssdkInitPromise = fetchWeChatJssdkSign(signPageUrl)
 				.then(function (sign) {
 					if (!sign) {
-						console.warn('[wx] getWxConfig empty');
+						setWxInitError('getWxConfig 返回为空');
 						return false;
 					}
 					if (sign.appId !== WECHAT_MP_APP_ID) {
-						console.warn(
-							'[wx] config appId=' +
-								sign.appId +
-								' 与 WECHAT_MP_APP_ID=' +
-								WECHAT_MP_APP_ID +
-								' 不一致,请后端用服务号 ID 签名'
+						setWxInitError(
+							'后端 appId=' + sign.appId + ',应为服务号 ' + WECHAT_MP_APP_ID
 						);
 					}
-					return applyWxConfig(sign, signPageUrl);
+					return applyWxConfig(sign, signPageUrl).then(function (ok) {
+						if (!ok && !wxInitLastError) {
+							setWxInitError('wx.config 失败,可加 ?wxDebug=1');
+						}
+						return ok;
+					});
 				})
 				.catch(function (e) {
+					setWxInitError(e && e.message ? e.message : 'getWxConfig 请求失败');
 					console.warn('[wx] init failed', e);
 					return false;
+				})
+				.finally(function () {
+					if (!weChatJssdkConfigured) wxJssdkInitPromise = null;
 				});
+
+			return wxJssdkInitPromise;
+		}
+
+		/** 进页即尝试拉签名;jweixin 晚到时自动重试 */
+		function scheduleWeChatJssdkBootstrap() {
+			if (!isWeChatInAppBrowser()) return;
+			var attempts = 0;
+			function tick() {
+				attempts += 1;
+				if (weChatJssdkConfigured) return;
+				initWeChatOpenLaunchApp();
+				if (!weChatJssdkConfigured && attempts < 8 && typeof wx === 'undefined') {
+					setTimeout(tick, 400);
+				}
+			}
+			tick();
+		}
+
+		function ensureWeChatJssdkReadyOnClick() {
+			wxJssdkInitPromise = null;
+			return initWeChatOpenLaunchApp().then(function (ok) {
+				if (ok) {
+					updateFabOpenLayer();
+					return true;
+				}
+				showAppOpenFailTip(
+					wxInitLastError
+						? 'JSSDK 未就绪:' + wxInitLastError
+						: 'JSSDK 未就绪:未请求到 getWxConfig'
+				);
+				return false;
+			});
 		}
 
 		function showAppOpenFailTip(msg) {
@@ -1506,9 +1577,7 @@
 				return;
 			}
 			if (inWx && !weChatJssdkConfigured) {
-				showAppOpenFailTip(
-					'微信内请先完成 JSSDK 配置(服务号 wx412792c77f47babd 签名)。可加 ?wxDebug=1 查看报错。'
-				);
+				ensureWeChatJssdkReadyOnClick();
 				return;
 			}
 
@@ -2712,9 +2781,6 @@
 		}
 
 		function boot() {
-			run();
-			bindMarketingMore();
-			bindStaffSection();
 			var launchTag = document.getElementById('launch-btn');
 			if (launchTag) launchTag.setAttribute('appid', WECHAT_OPEN_APP_ID);
 			var openBtn = document.getElementById('openApp');
@@ -2723,7 +2789,11 @@
 					tryOpenHBuilderApp();
 				});
 			}
-			initWeChatOpenLaunchApp();
+			/* 先于 run(),避免误以为没调 getWxConfig */
+			scheduleWeChatJssdkBootstrap();
+			run();
+			bindMarketingMore();
+			bindStaffSection();
 		}
 
 		if (document.readyState === 'complete') {