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 | 113 +++++++++++++++++++++++++++++++++++---------------------
1 files changed, 71 insertions(+), 42 deletions(-)
diff --git a/src/components/map/src/utils.ts b/src/components/map/src/utils.ts
index fb0bcbc..b170317 100644
--- a/src/components/map/src/utils.ts
+++ b/src/components/map/src/utils.ts
@@ -1,41 +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')銆嶃��
+ * 鍔犺浇鍦板潃浼樺厛绾э紙鎸夐『搴忓皾璇曪紝閮藉け璐ユ墠鎶ラ敊锛夛細
+ * 1. /bmap-api/getscript 鈥斺�� 鏈珯 nginx 鍙嶅悜浠g悊锛屽己鍒跺洖婧愮櫨搴� IPv4
+ * 2. https://api.map.baidu.com/getscript 鈥斺�� 鐩磋繛鐧惧害
*
- * getscript 杩斿洖鐨勬槸 875KB 鐨勭湡瀹� SDK锛堝凡瀹炴祴 HTTP 200 涓斿惈 BMapGL 瀹氫箟锛夛紝
- * 鐩存帴鐢� script.src 鍔犺浇鍗冲彲锛岃剼鏈墽琛屽畬 window.BMapGL 灏卞凡灏辩华銆�
+ * 涓轰粈涔堣浠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;
}
}
// 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;
}
@@ -45,38 +80,32 @@
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 瀛愯祫婧愬湴鍧�
+ 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;
+ 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}`,
+ ];
- script.addEventListener('load', () => {
- clearTimeout(timeoutId);
- if (!window.BMapGL) {
- // ak 鏃犳晥 / 鍩熷悕鏈巿鏉� / 琚嫤鎴椂锛岃剼鏈兘鍔犺浇浣嗕笉浼氭寕杞� BMapGL
- loadPromise = null;
- reject(
- new Error('鐧惧害鍦板浘鍔犺浇寮傚父锛氭湭鑾峰彇鍒板湴鍥惧璞★紝璇锋鏌� Key 鎴栧煙鍚嶆巿鏉�'),
- );
+ loadPromise = (async () => {
+ let lastError: any;
+ for (const url of candidates) {
+ try {
+ await loadFrom(url, timeout);
return;
+ } catch (error) {
+ lastError = error;
}
- resolve();
- });
-
- // 娉ㄦ剰锛氫簨浠跺悕鏄� error锛屼笉鏄� onerror锛堝啓 onerror 姘歌繙涓嶄細瑙﹀彂锛�
- script.addEventListener('error', () => {
- clearTimeout(timeoutId);
- loadPromise = null;
- reject(new Error('鐧惧害鍦板浘 SDK 鍔犺浇澶辫触锛岃妫�鏌ョ綉缁�'));
- });
-
- document.body.append(script);
- });
+ }
+ loadPromise = null;
+ throw new Error(
+ `鐧惧害鍦板浘 SDK 鍔犺浇澶辫触锛堝凡灏濊瘯浠g悊涓庣洿杩烇級锛�${lastError?.message ?? ''}`,
+ );
+ })();
return loadPromise;
};
--
Gitblit v1.9.3