首页 > 解决方案 > 使用 AJAX 避免 Google 地图收费,并仅在有人单击按钮时显示地图

问题描述

自 2018 年 7 月 16 日起,Google Maps API 不再完全免费。As of July 16, 2018, to continue to use the Google Maps Platform APIs, you must enable billing on each of your projects.https://developers.google.com/maps/documentation/javascript/usage-and-billing)。

我的问题是,在使用新的 Google Maps API 以及 Google 需要的相应密钥和计费信息一周后,我开始看到我的使用费用非常疯狂。这很好,因为这意味着我的网站有大量流量,我不应该专门抱怨这一点。问题是,可能我的绝大多数访问者甚至都没有看到/使用地图,而且一旦他们加载了一个有地图的页面,我仍然会被收费。

我的想法是默认不显示地图,并有一个显示“显示地图”的链接,以便我只向真正有兴趣查看地图的人显示地图。然后我想向 Google Maps API 发出 AJAX 请求。我知道并承认这是一种规避付款的方式,但我认为这是公平的游戏,因为我只想在访问者真正看到/与 Google 地图功能互动时才收取使用费,而不是在他们加载页面后立即收费我的网站。谷歌会允许我这样做还是会被视为作弊?查看https://developers.google.com/maps/documentation/javascript/tutorial上的代码。我的想法是在访问者单击“显示地图”按钮时使用 AJAX 请求调用此代码块,以尝试减少费用:

<div id="map"></div>
<script>
  var map;
  function initMap() {
    map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: -34.397, lng: 150.644},
      zoom: 8
    });
  }
</script>

更新 1:阅读AJAX 检索的 <div> 内的执行 <script>,Chocula 的回答说

作为 DOM 文本插入的 JavaScript 将不会执行。

那讲得通。考虑到尝试我在这个问题中所问的技术含义,考虑到 JavaScript 在作为 DOM 文本插入时不会执行,我怀疑它是否会起作用。问题是我将<script>...</script>使用 AJAX 生成该部分,作为 DOM 文本插入并且不会执行。如果我在页面加载后立即插入它,那么无论我是否通过显示<div id="map"></div>代码部分实际显示地图,我都会立即被收费。当人们甚至没有看到地图或对看到地图或与之交互不感兴趣时​​,这听起来像是一种有趣的方式来规避所有这些情况的付款,公平的游戏,但我认为我不能用 AJAX 做到这一点。

标签: javascriptajaxgoogle-mapsgoogle-maps-api-3maps

解决方案


您可能会做的是使用建议地图的占位符图像,加载 Javascript 但不调用地图函数(通常initMap在 Google 的示例中调用)

下面的例子过于夸张了,但或许可以让我了解我的建议。我正在通过谷歌控制台监控地图加载——简单地加载页面并没有增加计数器,但是一旦点击了地图并且正确地调用了地图,我发现配额计数器正在上升。

也许这可能有用...

<!DOCTYPE html>
<html lang='en'>
  <head>
    <meta charset='utf-8' />
    <title>Load a map on demand</title>
    <style>
        html, body {
            height:100vh;
            width:100%;
            margin: 0;
            padding: 0;
        }
        body{
            display:flex;
            align-items:center;
            justify-content:center;
            background:whitesmoke;
        }
        #map {
            height:90vh;
            width:90%;
            margin:auto;
            border:3px solid rgba(0,0,0,1);
        }
        .staticmap{
            background-image:url(/images/maps/static-map-scotland.jpg);
            background-position:top left;
            background-size:cover;
            display:flex;
            align-items:center;
            justify-content:center;
            border:3px solid rgba(0,0,0,0.25)!important;
        }
        /* use a pseudo element class to display a message */
        .staticmap:after{
            content:attr(data-info);
            font-size:3rem;
            color:red;
            width:100%;
            display:block;
            text-align:center;
        }
    </style>
    <script>
        document.addEventListener('DOMContentLoaded',function(){

            let map=document.getElementById('map');

            const initMap=function() {
                var default_location = {
                    lat:56.646577,
                    lng:-2.888609
                };
                map = new google.maps.Map( map, {
                    zoom: 10, 
                    center: default_location,
                    mapTypeId:'roadmap',
                    mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.DROPDOWN_MENU }
                });
                let options={
                    position:default_location,
                    map:map,
                    icon:'//maps.google.com/mapfiles/ms/icons/blue-pushpin.png',
                    title:'Default location'
                }

                marker = new google.maps.Marker( options );
            }


            /* let the user know to click the map if they need to use it's features */
            map.onmouseover=function(){ 
                this.dataset.info='Click on the map to load';
            };
            map.onmouseout=function(){
                this.dataset.info='';
            };

            document.querySelector('.staticmap').onclick=function(){
                if( confirm('Would you like to load the proper map?') ){

                    /* invoke the map fully */
                    initMap();

                    /* remove class that presented static image etc */
                    this.classList.remove('staticmap');
                }
            }
        },false);
    </script>






    <!--
        Rather than have the map initialisation run as a callback ( via the querystring parameter `callback=initMap` )
        or inline as a pageload function ( ie: `onload=initMap` etc ) do nothing at this stage.
    -->
    <script async defer src="//maps.googleapis.com/maps/api/js?key=APIKEY"></script>


  </head>
  <body>
    <div id='map' class='staticmap' data-info=''></div>
  </body>
</html>

示例 1:页面加载以显示表明地图可用的静态图像 单击地图以调用实际地图 实际地图现已加载... 谷歌控制台


推荐阅读