javascript - 使用 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 做到这一点。
解决方案
您可能会做的是使用建议地图的占位符图像,加载 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>
推荐阅读
- testing - 如何在 Postman 中从请求中设置变量
- docker - 在 Docker 上管理基于 apt-get 的依赖项
- python - 无法从多个页面中获取所有链接不变的 url
- node.js - Node.js 和 MongoDB Atlas Mongoose 连接错误
- sql - IS NULL 左连接
- java - 打印 IntStream 平均结果
- django - 使用通用 UpdateView 始终编辑单个配置对象
- python - 使用 asyncio.Queue 进行生产者-消费者流
- android - 使用最新的 NDK (r18) 在 Android 上启用 C++17
- python - 试图用python构造一个贪心算法