Google Maps Places API异常:部分页面出现'google.maps.places'未定义错误
问题:Google Maps Places API 在部分页面抛出 'google.maps.places' 未定义错误
我在使用Google Maps Places API为带有map-location类的输入框实现搜索自动补全并获取经纬度功能时,遇到如下问题:首页功能正常,但在部分其他页面中会抛出TypeError,提示'google.maps.places'未定义,控制台无其他额外错误提示。
相关代码如下:
<script src="https://maps.googleapis.com/maps/api/js?key={{ env('GOOGLE_MAPS_API_KEY') }}&loading=async&libraries=places"></script> <script> $(document).ready(function(){ function initAutocomplete() { $('.map-location').each(async(index, input) => { var autocomplete = await new google.maps.places.Autocomplete(input); autocomplete.addListener('place_changed', function() { var place = autocomplete.getPlace(); if (!place.geometry) { window.alert("No details available for input: '" + place.name + "'"); return; } var latitude = place.geometry.location.lat(); var longitude = place.geometry.location.lng(); $('input[name="latitude"]').val(latitude); $('input[name="longitude"]').val(longitude); console.log("Latitude: " + latitude + ", Longitude: " + longitude); }); }); } initAutocomplete(); }); </script>
问题原因
- 异步加载时序不匹配:使用
loading=async加载Google Maps脚本时,$(document).ready()仅等待DOM加载完成,不会等Google Maps的places库加载完毕就执行初始化代码。首页可能因缓存或脚本加载快刚好生效,其他页面加载慢就触发错误。 - 多余的async/await:
new google.maps.places.Autocomplete是同步操作,用await完全没必要,反而可能打乱执行逻辑。 - 字符串拼接语法错误:原代码里的弹窗和console语句存在引号嵌套错误,虽然不是直接导致API未定义的原因,但会引发后续逻辑问题。
修复方案
方案1:使用Google官方回调(最推荐)
利用Google Maps脚本的callback参数,确保API完全加载后再执行初始化:
<script src="https://maps.googleapis.com/maps/api/js?key={{ env('GOOGLE_MAPS_API_KEY') }}&libraries=places&callback=initAutocomplete" async defer></script> <script> function initAutocomplete() { // 先检查页面是否有目标输入框,避免无意义执行 const locationInputs = $('.map-location'); if (locationInputs.length === 0) return; locationInputs.each((index, input) => { const autocomplete = new google.maps.places.Autocomplete(input); autocomplete.addListener('place_changed', function() { const place = autocomplete.getPlace(); if (!place.geometry) { window.alert(`No details available for input: "${place.name}"`); return; } const latitude = place.geometry.location.lat(); const longitude = place.geometry.location.lng(); $('input[name="latitude"]').val(latitude); $('input[name="longitude"]').val(longitude); console.log(`Latitude: ${latitude}, Longitude: ${longitude}`); }); }); } </script>
- 移除
$(document).ready(),改用Google的callback触发初始化,保证API加载完成后才执行 - 添加
defer属性,确保脚本按顺序加载且不阻塞DOM解析 - 去掉多余的
async/await - 修复字符串拼接的引号错误,改用模板字符串更清晰
- 先判断输入框是否存在,避免无效执行
方案2:手动轮询API状态
如果必须保留$(document).ready(),可以手动轮询等待API加载完成:
<script src="https://maps.googleapis.com/maps/api/js?key={{ env('GOOGLE_MAPS_API_KEY') }}&loading=async&libraries=places"></script> <script> $(document).ready(function(){ function initAutocomplete() { const locationInputs = $('.map-location'); if (locationInputs.length === 0) return; locationInputs.each((index, input) => { const autocomplete = new google.maps.places.Autocomplete(input); autocomplete.addListener('place_changed', function() { const place = autocomplete.getPlace(); if (!place.geometry) { window.alert(`No details available for input: "${place.name}"`); return; } const latitude = place.geometry.location.lat(); const longitude = place.geometry.location.lng(); $('input[name="latitude"]').val(latitude); $('input[name="longitude"]').val(longitude); console.log(`Latitude: ${latitude}, Longitude: ${longitude}`); }); }); } // 轮询等待Google Places API加载完成 function waitForGoogleMaps() { if (typeof google !== 'undefined' && google.maps && google.maps.places) { initAutocomplete(); } else { setTimeout(waitForGoogleMaps, 100); } } waitForGoogleMaps(); }); </script>
- 增加轮询逻辑,直到
google.maps.places可用才执行初始化 - 同样修复了字符串错误和移除多余的
async/await
额外检查项
- 确认所有用到该功能的页面都加载了带
libraries=places参数的Google Maps脚本,部分页面可能漏加了这个参数 - 检查API密钥是否启用了Places API(首页能用大概率没问题,可登录Google Cloud控制台确认)
内容的提问来源于stack exchange,提问作者ANAS MK
相关产品推荐
相关产品推荐

