Procházet zdrojové kódy

修正调签名接口报错

zhuli před 3 týdny
rodič
revize
a56aac8499
1 změnil soubory, kde provedl 88 přidání a 9 odebrání
  1. 88 9
      HBuilderProjects/shareIndex.html

+ 88 - 9
HBuilderProjects/shareIndex.html

@@ -1039,8 +1039,15 @@
 		 */
 		var API_BASE = 'https://test.ailien.shop/alienStore';
 
-		/** 微信开放标签:移动应用 AppID(与 wx-open-launch-app appid 一致) */
+		/** 微信开放标签 wx-open-launch-app 的 appid(移动应用,与开放平台移动应用一致) */
 		var WECHAT_OPEN_APP_ID = 'wxff2fb6413a14a561';
+		/** 已知移动应用 AppID;getWxConfig 若只返回此类 id,不能用于 wx.config */
+		var WECHAT_KNOWN_MOBILE_APP_IDS = ['wxf5f1efe3a9f5012e', 'wxff2fb6413a14a561'];
+		/**
+		 * wx.config 必须用公众号 AppID(服务号)。若后端在 data 里单独返回 mpAppId / officialAppId 会优先使用。
+		 * 也可在分享链接加 ?wxMpAppId=wx公众号appid 临时联调(正式应由后端返回)。
+		 */
+		var WECHAT_MP_APP_ID = '';
 		/**
 		 * 进入页 GET {API_BASE}/wx/getWxConfig?url={页面地址,不含 query/hash}
 		 * 例:.../wx/getWxConfig?url=https://test.ailien.shop/h5/HBuilderProjects/shareIndex.html
@@ -1220,12 +1227,39 @@
 			return H5_PAGE_BASE_FALLBACK + rel;
 		}
 
+		function isWeChatMobileAppId(appId) {
+			var id = String(appId || '').trim();
+			if (!id) return false;
+			for (var i = 0; i < WECHAT_KNOWN_MOBILE_APP_IDS.length; i++) {
+				if (id === WECHAT_KNOWN_MOBILE_APP_IDS[i]) return true;
+			}
+			return false;
+		}
+
+		function resolveWxConfigAppIdFromSignData(d) {
+			if (!d || typeof d !== 'object') return '';
+			var mp =
+				d.mpAppId ||
+				d.mpAppid ||
+				d.officialAppId ||
+				d.officialAccountAppId ||
+				d.gzhAppId ||
+				d.serviceAppId;
+			if (mp != null && String(mp).trim() !== '') return String(mp).trim();
+			var fromQuery = String(q('wxMpAppId') || WECHAT_MP_APP_ID || '').trim();
+			if (fromQuery) return fromQuery;
+			var raw = d.appId || d.appid || d.wxAppId;
+			if (raw == null || String(raw).trim() === '') return '';
+			raw = String(raw).trim();
+			if (isWeChatMobileAppId(raw)) return '';
+			return raw;
+		}
+
 		function normalizeWxJssdkSignPayload(res) {
 			if (!res || typeof res !== 'object') return null;
 			var d = res.data != null && typeof res.data === 'object' ? res.data : res;
 			if (!d || typeof d !== 'object') return null;
-			/** wx.config 必须用公众号 appId;不可用移动应用 WECHAT_OPEN_APP_ID 顶替 */
-			var appId = d.appId || d.appid || d.wxAppId;
+			var appId = resolveWxConfigAppIdFromSignData(d);
 			var timestamp = d.timestamp != null ? d.timestamp : d.timeStamp;
 			var nonceStr = d.nonceStr || d.noncestr || d.nonce;
 			var signature = d.signature || d.sign;
@@ -1238,6 +1272,36 @@
 			};
 		}
 
+		function formatWxConfigErrorTip(err, signPageUrl, rawAppId) {
+			var errMsg = '';
+			if (err && err.errMsg) errMsg = String(err.errMsg);
+			else if (typeof err === 'string') errMsg = err;
+			var tip = '微信 JSSDK 配置失败';
+			if (rawAppId && isWeChatMobileAppId(rawAppId)) {
+				return (
+					tip +
+					':接口返回的 appId(' +
+					rawAppId +
+					')是移动应用 ID。wx.config 必须使用公众号 AppID,请后端用公众号 AppSecret 签名并返回公众号 appId(或 data.mpAppId)。'
+				);
+			}
+			if (/invalid signature/i.test(errMsg)) {
+				return (
+					tip +
+					':签名无效(invalid signature)。请确认后端签名使用的 url 与前端完全一致:' +
+					(signPageUrl || getWxConfigSignUrl())
+				);
+			}
+			if (/invalid appid/i.test(errMsg)) {
+				return tip + ':appId 无效,请使用已认证服务号的公众号 AppID。';
+			}
+			if (/invalid url/i.test(errMsg)) {
+				return tip + ':域名未在公众号 JS 接口安全域名中,或未在开放平台绑定域名与移动应用。';
+			}
+			if (errMsg) return tip + ':' + errMsg;
+			return tip + ',开放标签不可用。';
+		}
+
 		function fetchWeChatJssdkSign() {
 			var signPageUrl = getWxConfigSignUrl();
 			var urls = [];
@@ -1268,10 +1332,19 @@
 							}
 						}
 						var pack = normalizeWxJssdkSignPayload(res);
-						if (!pack) throw new Error('empty sign payload');
+						if (!pack) {
+							var rd =
+								res.data != null && typeof res.data === 'object' ? res.data : res;
+							var rawId = rd && (rd.appId || rd.appid) ? String(rd.appId || rd.appid) : '';
+							if (rawId && isWeChatMobileAppId(rawId)) {
+								return Promise.reject({ mobileAppId: rawId });
+							}
+							throw new Error('empty sign payload');
+						}
 						return pack;
 					})
-					.catch(function () {
+					.catch(function (err) {
+						if (err && err.mobileAppId) return Promise.reject(err);
 						return tryUrl(idx + 1);
 					});
 			}
@@ -1373,13 +1446,14 @@
 					}
 					bindWeChatLaunchTagEvents();
 					if (!sign) {
-						console.warn('[wx] GET ' + WECHAT_GET_WX_CONFIG_PATH + ' failed — check url param or ?wxSignPath=');
+						console.warn('[wx] GET ' + WECHAT_GET_WX_CONFIG_PATH + ' — invalid sign for wx.config');
 						showAppOpenFailTip(
-							'微信打开 App 需 GET /wx/getWxConfig 返回签名,当前未配置成功,无法使用「APP内打开」。'
+							formatWxConfigErrorTip(null, signPageUrl, 'wxf5f1efe3a9f5012e')
 						);
 						setFabLaunchMode('scheme');
 						return false;
 					}
+					console.log('[wx.config] appId=', sign.appId, 'signUrl=', signPageUrl);
 					return new Promise(function (resolve) {
 						wx.config({
 							debug: String(q('wxDebug') || '') === '1',
@@ -1387,7 +1461,7 @@
 							timestamp: sign.timestamp,
 							nonceStr: sign.nonceStr,
 							signature: sign.signature,
-							jsApiList: [],
+							jsApiList: ['checkJsApi'],
 							openTagList: ['wx-open-launch-app']
 						});
 						wx.ready(function () {
@@ -1404,7 +1478,7 @@
 						wx.error(function (err) {
 							console.warn('[wx.config]', err);
 							weChatJssdkConfigured = false;
-							showAppOpenFailTip('微信 JSSDK 配置失败,开放标签不可用。');
+							showAppOpenFailTip(formatWxConfigErrorTip(err, signPageUrl, ''));
 							setFabLaunchMode('scheme');
 							resolve(false);
 						});
@@ -1413,6 +1487,11 @@
 				.catch(function (e) {
 					console.warn('[wx] init failed', e);
 					if (inWx) {
+						if (e && e.mobileAppId) {
+							showAppOpenFailTip(
+								formatWxConfigErrorTip(null, signPageUrl, e.mobileAppId)
+							);
+						}
 						setFabLaunchMode('scheme');
 					}
 					return false;