| | |
| | | /** |
| | | * ç¾åº¦å°å¾ 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 ä¼è¢«æµè§å¨æ¦æª |
| | | * ï¼Chrome ç´æ¥æç¤º "A parser-blocking, cross site script ... invoked via document.write was NOT executed"ï¼ï¼ |
| | | * 导è´çæ£ç SDK 仿ªå è½½ãwindow.BMapGL ä¸ç´æ¯ undefined/nullã |
| | | * ä½ api éç callback ä»ä¼è¢«è°ç¨ï¼è°ç¨æ¹è¯¯ä»¥ä¸ºå è½½æåï¼æ¥çæ§è¡ new BMapGL.Map() |
| | | * å°±æåºãCannot 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 仿ªæ§è¡ãwindow.BMapGL ä¸ç´æ¯ç©ºï¼ä½ api ç callback ä»ä¼è¢«è°ç¨ï¼ |
| | | * è°ç¨æ¹è¯¯å¤æåï¼æ¥ç new BMapGL.Map() å°±æ |
| | | * "Cannot read properties of null (reading 'Map')"ã |
| | | * |
| | | * 2. å¿
é¡»ç´è¿ getscriptï¼å®æ¯ 875KB ççå® SDKã |
| | | * |
| | | * 3. å è½½åè¦è®¾ç½® window.BMAP_PROTOCOL = 'https'ï¼ç¾åº¦å®æ¹è¦æ±ï¼ï¼ |
| | | * å¦å SDK å
鍿é»è®¤åè®®æ¼åèµæºå°åï¼HTTPS 页é¢ä¸ä¼è¢«å½ä½æ··åå
å®¹æ¦æªã |
| | | * |
| | | * 4. ä¸è¦ç» script å async = trueï¼SDK å
é¨ç¨ 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ï¼SDK ä¾èµ 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 |
| | |
| | | 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; |
| | | }; |