From 23b513b644720666c5bda5073b34567cbadbbe4a Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期四, 05 十一月 2026 16:45:03 +0800
Subject: [PATCH] fix(map): 按百度官方规范修正 SDK 加载,并加诊断页定位线上加载失败

---
 src/components/map/src/utils.ts |  115 ++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 76 insertions(+), 39 deletions(-)

diff --git a/src/components/map/src/utils.ts b/src/components/map/src/utils.ts
index fb0bcbc..8937315 100644
--- a/src/components/map/src/utils.ts
+++ b/src/components/map/src/utils.ts
@@ -1,28 +1,76 @@
 /**
  * 鐧惧害鍦板浘 SDK 鍔犺浇宸ュ叿
  *
- * 閲嶈锛氳繖閲屽繀椤荤洿杩� getscript锛屼笉鑳界敤 api?... 鍦板潃銆�
- * api?v=1.0&type=webgl&ak=xxx 杩斿洖鐨勬槸涓�娈�
- *   document.write('<script src="https://api.map.baidu.com/getscript?..."></script>')
- * 鑰岄�氳繃 document.body.append(script) 鍔ㄦ�佹彃鍏ョ殑鑴氭湰閲岋紝document.write 浼氳娴忚鍣ㄦ嫤鎴�
- * 锛圕hrome 鐩存帴鎻愮ず "A parser-blocking, cross site script ... invoked via document.write was NOT executed"锛夛紝
- * 瀵艰嚧鐪熸鐨� SDK 浠庢湭鍔犺浇銆亀indow.BMapGL 涓�鐩存槸 undefined/null銆�
- * 浣� api 閲岀殑 callback 浠嶄細琚皟鐢紝璋冪敤鏂硅浠ヤ负鍔犺浇鎴愬姛锛屾帴鐫�鎵ц new BMapGL.Map()
- * 灏辨姏鍑恒�孋annot read properties of null (reading 'Map')銆嶃��
+ * 鍔犺浇鏂瑰紡璇存槑锛堣俯杩囩殑鍧戯級锛�
  *
- * getscript 杩斿洖鐨勬槸 875KB 鐨勭湡瀹� SDK锛堝凡瀹炴祴 HTTP 200 涓斿惈 BMapGL 瀹氫箟锛夛紝
- * 鐩存帴鐢� script.src 鍔犺浇鍗冲彲锛岃剼鏈墽琛屽畬 window.BMapGL 灏卞凡灏辩华銆�
+ * 1. 涓嶈兘鐢� api?v=1.0&type=webgl&ak=xxx 杩欎釜鍦板潃銆�
+ *    瀹冭繑鍥炵殑鏄竴娈� document.write('<script src=".../getscript?...">')锛�
+ *    鑰岄�氳繃 document.body.append(script) 鍔ㄦ�佹彃鍏ョ殑鑴氭湰閲� document.write 浼氳娴忚鍣ㄦ嫤鎴紝
+ *    瀵艰嚧鐪熸鐨� SDK 浠庢湭鎵ц銆亀indow.BMapGL 涓�鐩存槸绌猴紱浣� api 鐨� callback 浠嶄細琚皟鐢紝
+ *    璋冪敤鏂硅鍒ゆ垚鍔燂紝鎺ョ潃 new BMapGL.Map() 灏辨姏
+ *    "Cannot read properties of null (reading 'Map')"銆�
+ *
+ * 2. 蹇呴』鐩磋繛 getscript锛屽畠鏄� 875KB 鐨勭湡瀹� SDK銆�
+ *
+ * 3. 鍔犺浇鍓嶈璁剧疆 window.BMAP_PROTOCOL = 'https'锛堢櫨搴﹀畼鏂硅姹傦級锛�
+ *    鍚﹀垯 SDK 鍐呴儴鎸夐粯璁ゅ崗璁嫾瀛愯祫婧愬湴鍧�锛孒TTPS 椤甸潰涓嬩細琚綋浣滄贩鍚堝唴瀹规嫤鎴��
+ *
+ * 4. 涓嶈缁� script 鍔� async = true锛歋DK 鍐呴儴鐢� document.currentScript 瀹氫綅鑷韩锛�
+ *    async 鑴氭湰鎵ц鏈熼棿 currentScript 涓� null锛屼細璁╁畠璧板埌 fallback 鍒嗘敮鐢氳嚦鎷夸笉鍒拌嚜韬湴鍧�銆�
+ *
+ * 5. 澶辫触閲嶈瘯涓�娆★細鍋跺彂缃戠粶鎶栧姩锛堝挨鍏舵槸璺ㄧ渷/绉诲姩缃戠粶锛夐噸璇曞線寰�灏辫兘杩囥��
  */
 
 // 鎵╁睍 Window 鎺ュ彛浠ュ寘鍚櫨搴﹀湴鍥� GL API
 declare global {
   interface Window {
     BMapGL: any;
+    BMAP_PROTOCOL: any;
+    BMapGL_loadScriptTime: any;
   }
 }
 
 // SDK 鍔犺浇鐘舵��
 let loadPromise: null | Promise<void> = null;
+// 鍔犺浇澶辫触娆℃暟锛岀敤浜庡喅瀹氭槸鍚﹂噸璇�
+let failCount = 0;
+
+/** 鍗曟灏濊瘯鍔犺浇 */
+function loadOnce(accessKey: string, timeout: number): Promise<void> {
+  return new Promise((resolve, reject) => {
+    const timeoutId = setTimeout(() => {
+      reject(new Error('鐧惧害鍦板浘 SDK 鍔犺浇瓒呮椂锛岃妫�鏌ョ綉缁�'));
+    }, timeout);
+
+    const script = document.createElement('script');
+    script.src = `https://api.map.baidu.com/getscript?type=webgl&v=1.0&ak=${accessKey}&services=&t=${Date.now()}`;
+    // 娉ㄦ剰锛氫笉瑕佽 async锛孲DK 渚濊禆 document.currentScript 瀹氫綅鑷韩
+
+    script.addEventListener('load', () => {
+      clearTimeout(timeoutId);
+      if (!window.BMapGL) {
+        // ak 鏃犳晥 / 鍩熷悕鏈巿鏉� / 琚嫤鎴椂锛岃剼鏈兘鍔犺浇浣嗕笉浼氭寕杞� BMapGL
+        reject(
+          new Error('鐧惧害鍦板浘鍔犺浇寮傚父锛氭湭鑾峰彇鍒板湴鍥惧璞★紝璇锋鏌� Key 鎴栧煙鍚嶆巿鏉�'),
+        );
+        return;
+      }
+      resolve();
+    });
+
+    // 浜嬩欢鍚嶆槸 error锛屼笉鏄� onerror锛堝啓 onerror 姘歌繙涓嶄細瑙﹀彂锛�
+    script.addEventListener('error', () => {
+      clearTimeout(timeoutId);
+      reject(
+        new Error(
+          '鐧惧害鍦板浘 SDK 鍔犺浇澶辫触锛堟棤娉曡闂� api.map.baidu.com锛屽彲鑳芥槸缃戠粶闄愬埗鎴栨彃浠舵嫤鎴級',
+        ),
+      );
+    });
+
+    document.body.append(script);
+  });
+}
 
 /**
  * 鍔犺浇鐧惧害鍦板浘 GL SDK
@@ -45,38 +93,27 @@
     return Promise.reject(new Error('鏈厤缃� VITE_BAIDU_MAP_KEY'));
   }
 
-  loadPromise = new Promise((resolve, reject) => {
-    const timeoutId = setTimeout(() => {
-      loadPromise = null;
-      reject(new Error('鐧惧害鍦板浘 SDK 鍔犺浇瓒呮椂锛岃妫�鏌ョ綉缁�'));
-    }, timeout);
+  // 鐧惧害瀹樻柟瑕佹眰锛氬厛澹版槑鍗忚锛岄伩鍏� HTTPS 椤甸潰涓� SDK 鎷煎嚭 http 瀛愯祫婧愬湴鍧�
+  if (typeof window !== 'undefined') {
+    window.BMAP_PROTOCOL = 'https';
+    window.BMapGL_loadScriptTime = Date.now();
+  }
 
-    const script = document.createElement('script');
-    script.src = `https://api.map.baidu.com/getscript?type=webgl&v=1.0&ak=${accessKey}&services=&t=${Date.now()}`;
-    script.async = true;
-
-    script.addEventListener('load', () => {
-      clearTimeout(timeoutId);
-      if (!window.BMapGL) {
-        // ak 鏃犳晥 / 鍩熷悕鏈巿鏉� / 琚嫤鎴椂锛岃剼鏈兘鍔犺浇浣嗕笉浼氭寕杞� BMapGL
+  loadPromise = (async () => {
+    try {
+      await loadOnce(accessKey, timeout);
+    } catch (error) {
+      // 棣栨澶辫触閲嶈瘯涓�娆★紝搴斿鍋跺彂缃戠粶鎶栧姩
+      if (failCount < 1) {
+        failCount += 1;
+        await loadOnce(accessKey, timeout);
+      } else {
+        failCount = 0;
         loadPromise = null;
-        reject(
-          new Error('鐧惧害鍦板浘鍔犺浇寮傚父锛氭湭鑾峰彇鍒板湴鍥惧璞★紝璇锋鏌� Key 鎴栧煙鍚嶆巿鏉�'),
-        );
-        return;
+        throw error;
       }
-      resolve();
-    });
-
-    // 娉ㄦ剰锛氫簨浠跺悕鏄� error锛屼笉鏄� onerror锛堝啓 onerror 姘歌繙涓嶄細瑙﹀彂锛�
-    script.addEventListener('error', () => {
-      clearTimeout(timeoutId);
-      loadPromise = null;
-      reject(new Error('鐧惧害鍦板浘 SDK 鍔犺浇澶辫触锛岃妫�鏌ョ綉缁�'));
-    });
-
-    document.body.append(script);
-  });
+    }
+  })();
 
   return loadPromise;
 };

--
Gitblit v1.9.3