فهرست منبع

动态微信唤起app

zhuli 1 هفته پیش
والد
کامیت
5d7769f360
1فایلهای تغییر یافته به همراه89 افزوده شده و 23 حذف شده
  1. 89 23
      HBuilderProjects/shareDynamic.html

+ 89 - 23
HBuilderProjects/shareDynamic.html

@@ -804,33 +804,77 @@
 			return pathPart.replace(/^\/+/, '');
 		}
 
-		function buildAppOpenQueryStringMerged() {
-			var params = mergeSearchAndHashParams();
+		function appendFromShareDynamicToRaw(qs) {
+			var s = String(qs || '').trim();
+			if (!s) return 'fromShareDynamic=1';
+			var pad = '&' + s + '&';
+			if (/[&?](fromShareDynamic|FROMSHAREDYNAMIC)=/i.test(pad)) return s;
+			return s + '&fromShareDynamic=1';
+		}
 
-			/**
-			 * 唤起 newdetails 与 H5 **query 原样一致**:用浏览器地址栏原始串 + `fromShareDynamic=1`,
-			 * 避免 item 经 JSON.stringify / URLSearchParams 再编码与微信落地链不一致。
-			 * 仅「仅有 search」或「仅有 hash 内 ? 段」时走此路径;二者皆有或皆无则走下方补全。
-			 */
-			var rawSearch = location.search && location.search.length > 1 ? location.search.slice(1) : '';
+		function rawQueryHasItem(qs) {
+			return /(?:^|&)item=/i.test('&' + String(qs || '') + '&');
+		}
+
+		/**
+		 * 唤起 App / 微信 extinfo:优先原样透传地址栏 query(保留 item 双重编码、OSS 内 & 不被拆参)。
+		 * search 与 hash 同时存在时:含 item 的一侧优先,否则 hash 覆盖 search(与 mergeSearchAndHashParams 一致)。
+		 */
+		function getRawMergedQueryForAppOpen() {
+			var rawSearch =
+				location.search && location.search.length > 1 ? location.search.slice(1) : '';
 			var hash0 = location.hash || '';
 			var hqi0 = hash0.indexOf('?');
 			var rawHashQ = hqi0 >= 0 ? hash0.slice(hqi0 + 1) : '';
-			function appendFromShareDynamicToRaw(qs) {
-				var s = String(qs || '').trim();
-				if (!s) return 'fromShareDynamic=1';
-				var pad = '&' + s + '&';
-				if (/[&?](fromShareDynamic|FROMSHAREDYNAMIC)=/i.test(pad)) return s;
-				return s + '&fromShareDynamic=1';
+
+			if (!rawSearch && !rawHashQ) return '';
+
+			if (rawHashQ && rawSearch) {
+				if (rawQueryHasItem(rawHashQ)) return rawHashQ;
+				if (rawQueryHasItem(rawSearch)) return rawSearch;
+				return rawHashQ;
 			}
-			if (rawSearch && !rawHashQ) {
-				return '?' + appendFromShareDynamicToRaw(rawSearch);
+			return rawHashQ || rawSearch;
+		}
+
+		/** 从原始 query 串截取 item= 值(不 decode),供微信 extinfo 限长时保留编码 */
+		function extractRawItemParamFromQuery(qs) {
+			var pad = '&' + String(qs || '') + '&';
+			var m = /&item=([^&]*)/i.exec(pad);
+			return m ? m[1] : '';
+		}
+
+		/** App / 微信 extinfo:item 须双重 URL 编码;已是 %257B… 则不再编码 */
+		function formatItemForShoproQuery(rawItem) {
+			var s = String(rawItem || '').trim();
+			if (!s) return '';
+			if (/^%25(?:7B|5B|22)/i.test(s)) {
+				return s;
+			}
+			if (/^%7B/i.test(s)) {
+				return encodeURIComponent(s);
+			}
+			var parsed = tryParseJsonObject(s);
+			if (parsed) {
+				try {
+					return encodeURIComponent(encodeURIComponent(JSON.stringify(parsed)));
+				} catch (eJson) {}
 			}
-			if (!rawSearch && rawHashQ) {
-				return '?' + appendFromShareDynamicToRaw(rawHashQ);
+			if (s.charAt(0) === '{' || s.charAt(0) === '[') {
+				return encodeURIComponent(encodeURIComponent(s));
+			}
+			return encodeURIComponent(encodeURIComponent(s));
+		}
+
+		function buildAppOpenQueryStringMerged() {
+			var rawQs = getRawMergedQueryForAppOpen();
+			if (rawQs) {
+				return '?' + appendFromShareDynamicToRaw(rawQs);
 			}
 
-			/** newdetails onLoad:仅当地址栏未带 item 时补全;同时按需补顶层 imagePath */
+			var params = mergeSearchAndHashParams();
+
+			/** 地址栏无任何 query 时再补全 item / imagePath */
 			if (!params.has('item')) {
 				var itemObj = parseOptionsItem();
 				var imagePath = getMergedParam('imagePath');
@@ -940,10 +984,7 @@
 				fhfRaw != null && String(fhfRaw).trim() !== '' ? String(fhfRaw).trim() : '1';
 			var segs = [];
 			if (itemForShopro && String(itemForShopro).trim()) {
-				segs.push(
-					'item=' +
-						encodeURIComponent(encodeURIComponent(String(itemForShopro).trim()))
-				);
+				segs.push('item=' + formatItemForShoproQuery(itemForShopro));
 			}
 			segs.push('needShowMore=' + encodeURIComponent(nsmOut));
 			segs.push('fromHomeFeed=' + encodeURIComponent(fhfOut));
@@ -1061,6 +1102,30 @@
 				return deepOther.slice(0, 1024);
 			}
 
+			/** 微信 extinfo ≤1024:优先保留原始 item= 编码 + 关键开关,避免重建 query 导致 App 解析失败 */
+			var rawQs = getRawMergedQueryForAppOpen();
+			if (rawQs) {
+				var itemRaw = extractRawItemParamFromQuery(rawQs);
+				var nsmWx = getMergedParam('needShowMore');
+				var nsmOutWx =
+					nsmWx != null && String(nsmWx).trim() !== '' ? String(nsmWx).trim() : 'true';
+				var fhfWx = getMergedParam('fromHomeFeed');
+				var fhfOutWx =
+					fhfWx != null && String(fhfWx).trim() !== '' ? String(fhfWx).trim() : '1';
+				var wxSegs = [];
+				if (itemRaw) wxSegs.push('item=' + itemRaw);
+				wxSegs.push('needShowMore=' + encodeURIComponent(nsmOutWx));
+				wxSegs.push('fromHomeFeed=' + encodeURIComponent(fhfOutWx));
+				wxSegs.push('fromShareDynamic=1');
+				var stWx =
+					getMergedParam('sourceType') ||
+					getMergedParam('type') ||
+					'';
+				if (stWx) wxSegs.push('sourceType=' + encodeURIComponent(String(stWx).trim()));
+				var packedWx = path + '?' + wxSegs.join('&');
+				if (packedWx.length <= 1024) return packedWx;
+			}
+
 			var blob = parseShareDynamicItemBlob();
 			var mini = new URLSearchParams();
 			if (blob && blob.id != null && String(blob.id).trim() !== '') {
@@ -1073,6 +1138,7 @@
 				getMergedParam('type') ||
 				(blob && blob.type != null ? String(blob.type) : '');
 			if (st) mini.set('sourceType', st);
+			else mini.set('sourceType', '1');
 			var nsmRaw = getMergedParam('needShowMore');
 			if (nsmRaw != null && String(nsmRaw).trim() !== '') {
 				mini.set('needShowMore', String(nsmRaw).trim());