From 3b8ba54ea299a9febdf3a989a72b4eba311be796 Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期四, 05 十一月 2026 16:51:57 +0800
Subject: [PATCH] fix(map): SDK 改走同域反向代理,绕开客户端 IPv6 不通

---
 src/components/map/src/utils.ts |  112 ++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 80 insertions(+), 32 deletions(-)

diff --git a/src/components/map/src/utils.ts b/src/components/map/src/utils.ts
index c5ff378..b170317 100644
--- a/src/components/map/src/utils.ts
+++ b/src/components/map/src/utils.ts
@@ -1,63 +1,111 @@
-/* eslint-disable @typescript-eslint/no-dynamic-delete */
 /**
  * 鐧惧害鍦板浘 SDK 鍔犺浇宸ュ叿
+ *
+ * 鍔犺浇鍦板潃浼樺厛绾э紙鎸夐『搴忓皾璇曪紝閮藉け璐ユ墠鎶ラ敊锛夛細
+ *   1. /bmap-api/getscript  鈥斺�� 鏈珯 nginx 鍙嶅悜浠g悊锛屽己鍒跺洖婧愮櫨搴� IPv4
+ *   2. https://api.map.baidu.com/getscript 鈥斺�� 鐩磋繛鐧惧害
+ *
+ * 涓轰粈涔堣浠g悊锛堝疄娴嬬粨璁猴級锛�
+ *   璇ラ儴缃茬幆澧冿紙鍚鎴风鎵�鍦ㄧ綉缁滐級IPv6 涓嶉�氾紝鑰� api.map.baidu.com 鐨� DNS
+ *   浼樺厛杩斿洖 AAAA锛圛Pv6锛夎褰曪紝娴忚鍣ㄤ紭鍏堣繛 IPv6 鏃剁珛鍗冲け璐モ�斺��
+ *   script 鐨� error 浜嬩欢鍦� 1 绉掑唴灏辫Е鍙戯紝鏍规湰涓嶆槸瓒呮椂銆�
+ *   鏈嶅姟鍣ㄤ晶楠岃瘉锛歝url -4 寰楀埌 HTTP 200 / 0.94s锛宑url -6 鐩存帴澶辫触銆�
+ *   璧板悓鍩熶唬鐞嗗悗锛屽鎴风鍙闂湰鏈� 9023锛岀敱鏈嶅姟鍣ㄧ敤鍥哄畾 IPv4 鍥炴簮锛�
+ *   瀹炴祴 HTTP 200 / 879KB / 0.28s銆�
+ *
+ * 鍏朵粬韪╄繃鐨勫潙锛�
+ *   - 涓嶈兘鐢� api?v=1.0&type=webgl锛堣繑鍥� document.write 鍖呰锛屽姩鎬佽剼鏈噷浼氳娴忚鍣ㄦ嫤鎴級
+ *   - 鍔犺浇鍓嶈璁� window.BMAP_PROTOCOL = 'https'锛堢櫨搴﹀畼鏂硅姹傦級
+ *   - 涓嶈缁� script 鍔� async锛圫DK 渚濊禆 document.currentScript 瀹氫綅鑷韩锛�
+ *   - script 鐨勪簨浠跺悕鏄� error锛屼笉鏄� onerror
  */
 
 // 鎵╁睍 Window 鎺ュ彛浠ュ寘鍚櫨搴﹀湴鍥� GL API
 declare global {
   interface Window {
     BMapGL: any;
+    BMAP_PROTOCOL: any;
+    BMapGL_loadScriptTime: any;
   }
 }
-
-// 鍏ㄥ眬鍥炶皟鍚嶇О
-const CALLBACK_NAME = '__BAIDU_MAP_LOAD_CALLBACK__';
 
 // SDK 鍔犺浇鐘舵��
 let loadPromise: null | Promise<void> = null;
 
+/** 鐢ㄦ寚瀹氬湴鍧�鍔犺浇涓�娆� */
+function loadFrom(url: string, timeout: number): Promise<void> {
+  return new Promise((resolve, reject) => {
+    const timeoutId = setTimeout(() => {
+      reject(new Error(`鐧惧害鍦板浘 SDK 鍔犺浇瓒呮椂锛�${url}`));
+    }, timeout);
+
+    const script = document.createElement('script');
+    script.src = url;
+    // 娉ㄦ剰锛氫笉瑕佽 async锛孲DK 渚濊禆 document.currentScript 瀹氫綅鑷韩
+
+    script.addEventListener('load', () => {
+      clearTimeout(timeoutId);
+      if (!window.BMapGL) {
+        reject(new Error('鑴氭湰宸蹭笅杞戒絾鏈寕杞藉湴鍥惧璞�'));
+        return;
+      }
+      resolve();
+    });
+
+    // 浜嬩欢鍚嶆槸 error锛屼笉鏄� onerror锛堝啓 onerror 姘歌繙涓嶄細瑙﹀彂锛�
+    script.addEventListener('error', () => {
+      clearTimeout(timeoutId);
+      reject(new Error(`鍔犺浇澶辫触锛�${url}`));
+    });
+
+    document.body.append(script);
+  });
+}
+
 /**
  * 鍔犺浇鐧惧害鍦板浘 GL SDK
- * @param timeout 瓒呮椂鏃堕棿锛堟绉掞級锛岄粯璁� 10000
+ * @param timeout 鍗曟灏濊瘯鐨勮秴鏃舵椂闂达紙姣锛夛紝榛樿 10000
  * @returns Promise<void>
  */
 export const loadBaiduMapSdk = (timeout = 10_000): Promise<void> => {
-  // 宸插姞杞藉畬鎴�
   if (window.BMapGL) {
     return Promise.resolve();
   }
-
-  // 姝e湪鍔犺浇涓紝杩斿洖鍚屼竴涓� Promise
   if (loadPromise) {
     return loadPromise;
   }
 
-  loadPromise = new Promise((resolve, reject) => {
-    const timeoutId = setTimeout(() => {
-      loadPromise = null;
-      reject(new Error('鐧惧害鍦板浘 SDK 鍔犺浇瓒呮椂'));
-    }, timeout);
+  const accessKey = String(import.meta.env.VITE_BAIDU_MAP_KEY ?? '').trim();
+  if (!accessKey) {
+    return Promise.reject(new Error('鏈厤缃� VITE_BAIDU_MAP_KEY'));
+  }
 
-    // 鍏ㄥ眬鍥炶皟
-    (window as any)[CALLBACK_NAME] = () => {
-      clearTimeout(timeoutId);
-      delete (window as any)[CALLBACK_NAME];
-      resolve();
-    };
+  // 鐧惧害瀹樻柟瑕佹眰锛氬厛澹版槑鍗忚锛岄伩鍏� HTTPS 椤甸潰涓� SDK 鎷煎嚭 http 瀛愯祫婧愬湴鍧�
+  window.BMAP_PROTOCOL = 'https';
+  window.BMapGL_loadScriptTime = Date.now();
 
-    // 鍒涘缓 script 鏍囩
-    const script = document.createElement('script');
-    script.src = `https://api.map.baidu.com/api?v=1.0&type=webgl&ak=${
-      import.meta.env.VITE_BAIDU_MAP_KEY
-    }&callback=${CALLBACK_NAME}`;
-    script.addEventListener('onerror', () => {
-      clearTimeout(timeoutId);
-      loadPromise = null;
-      delete (window as any)[CALLBACK_NAME];
-      reject(new Error('鐧惧害鍦板浘 SDK 鍔犺浇澶辫触'));
-    });
-    document.body.append(script);
-  });
+  const query = `type=webgl&v=1.0&ak=${accessKey}&services=&t=${Date.now()}`;
+  // 浼樺厛鍚屽煙鍙嶄唬锛堢粫杩囧鎴风 IPv6 涓嶉�氾級锛屽啀鍥為��鐩磋繛
+  const candidates = [
+    `/bmap-api/getscript?${query}`,
+    `https://api.map.baidu.com/getscript?${query}`,
+  ];
+
+  loadPromise = (async () => {
+    let lastError: any;
+    for (const url of candidates) {
+      try {
+        await loadFrom(url, timeout);
+        return;
+      } catch (error) {
+        lastError = error;
+      }
+    }
+    loadPromise = null;
+    throw new Error(
+      `鐧惧害鍦板浘 SDK 鍔犺浇澶辫触锛堝凡灏濊瘯浠g悊涓庣洿杩烇級锛�${lastError?.message ?? ''}`,
+    );
+  })();
 
   return loadPromise;
 };

--
Gitblit v1.9.3