Apps Script中Maps JavaScript API动态库导入失败求助
Google Apps Script中Google Maps动态库导入API报错解决方案
问题概述
尝试从传统script标签切换到Google Maps Dynamic Library Import API,在Google表格的Apps Script中编写示例代码后,浏览器控制台出现以下错误:
userCodeAppPanel:2 Uncaught SyntaxError: Unexpected end of input
userCodeAppPanel:6 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'importLibrary') at initMap (userCodeAppPanel:6:39) at userCodeAppPanel:15:1
修复引号问题后仍存在错误:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'importLibrary')
相同代码在JSFiddle中可正常运行,推测是Apps Script的特殊环境导致配置或解析问题。
原代码如下:
<!doctype html> <html> <head> <title>Simple Map</title> <script> let map; // initMap is now async async function initMap() { // Request libraries when needed, not in the script tag. const { Map } = await google.maps.importLibrary("maps"); // Short namespaces can be used. map = new Map(document.getElementById("map"), { center: { lat: 40.72476, lng: -74.04843 }, zoom: 8, }); } initMap(); </script> </head> <body> <div id="map"></div> <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src="https://maps.${c}apis.com/maps/api/js?"+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))}) ({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "weekly"});</script> <style> #map { height: 100%; } html, body { height: 100%; margin: 0; padding: 0; background-color: grey; } </style> </body> </html>
错误原因分析
- 模板字符串解析失败:原代码中
a.src="https://maps.${c}apis.com/maps/api/js?"+e;使用模板字符串语法但被双引号包裹,Apps Script解析时会将${c}当作普通字符串处理,导致请求的地图API URL无效。 - 执行时机不匹配:
initMap()被同步调用,但动态导入的初始化脚本尚未完成加载,此时google.maps对象还未挂载importLibrary方法。 - HTML转义问题:Apps Script对HTML模板中的特殊字符(如
")转义处理,导致脚本逻辑出现语法错误。
解决方案
修正后的代码
<!doctype html> <html> <head> <title>Simple Map</title> <style> #map { height: 100%; } html, body { height: 100%; margin: 0; padding: 0; background-color: grey; } </style> </head> <body> <div id="map"></div> <script> let map; async function initMap() { // 确保importLibrary方法存在后再执行,兼容加载延迟情况 if (!google?.maps?.importLibrary) { await new Promise(resolve => setTimeout(resolve, 100)); return initMap(); } const { Map } = await google.maps.importLibrary("maps"); map = new Map(document.getElementById("map"), { center: { lat: 40.72476, lng: -74.04843 }, zoom: 8, }); } </script> <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))}) ({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "weekly"}); // 等待动态脚本初始化完成后调用地图初始化 google.maps.__ib__().then(initMap); </script> </body> </html>
关键修正点
- 修复URL模板字符串:将
a.src的双引号改为反引号,确保${c}被正确解析为google,生成有效的API请求地址。 - 调整执行时机:通过
google.maps.__ib__().then(initMap)确保动态导入脚本完全初始化后,再调用地图初始化函数。 - 增加重试逻辑:在
initMap中加入延迟重试机制,避免极端情况下脚本加载延迟导致的方法未定义问题。 - 移除不必要转义:将
"替换为普通双引号,避免Apps Script的转义处理引发语法错误。
Apps Script额外配置注意
- 使用
HtmlService.createHtmlOutputFromFile("你的HTML文件名")加载HTML内容,而非直接拼接字符串,减少转义问题。 - 部署Web应用时,确保访问权限设置符合需求(如允许匿名访问或指定域访问)。
内容的提问来源于stack exchange,提问作者Volodymyr
相关产品推荐
相关产品推荐

