Google 地点 APi 照片
Google Places APi photo
我正在尝试使用 php 为我的网站呈现图像,该图像将直接动态显示来自 Google 地点 API 的图像(参考 https://developers.google.com/places/web-service/photos?hl=en)
图像源类似于以下示例:
https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=CnRtAAAATLZNl354RwP_9UKbQ_5Psy40texXePv4oAlgP4qNEkdIrkyse7rPXYGd9D_Uj1rVsQdWT4oRz4QrYAJNpFX7rzqqMlZw2h2E2y5IKMUZ7ouD_SlcHxYq1yL4KbKUv3qtWgTK0A6QbGh87GB3sscrHRIQiG2RrmU_jF4tENr9wGS_YxoUSSDrYjWmrNfeEHSGSc3FyhNLlBU&key=API_KEY
如果您通过浏览器访问此 URL,它将呈现一个图像,这不再是您看到的 URL。
我的问题是,当查看页面源时,这正是您看到的图像源 URL,这是错误的,因为我的密钥随后被公开了。在保持我的密钥私密性的同时呈现图像的正确方法是什么?我为此在 API 和网上进行了搜索,但无济于事。我确实看到了一些使用 file_get_contents 和 file_put_contents 的技巧,但我的虚拟主机不允许这样做。最后,保存图像违反了 api 规则,所以这不是一个选项。
如有任何提示,我们将不胜感激。提前致谢。
您可以向特定的 URL 发送 HEAD 请求并提取 Location
-header 的内容:
<?php
$context = stream_context_create(array('http' =>array('method'=>'HEAD')));
$fp = fopen('desiredPlacesApiImgUrl', 'rb', false, $context);
$meta = stream_get_meta_data($fp);
if(isset($meta['wrapper_data'])){
$location=preg_grep('@^\s*Location:@',$meta['wrapper_data']);
if(count($location)){
$imgUrl=trim(preg_replace('@^Location:@i','',reset($location)));
die($imgUrl);//the desired img-url
}
}
fclose($fp);
?>
但是当你的服务器上不允许 file_get_contents
恐怕 fopen
也不允许外部 URLs.
另一种选择:使用地图-Javascript-API,请求地点,响应应包含所需的URL(不使用任何键)。
演示:
function loadPlacePhotos() {
var photos = document.querySelectorAll('img[data-place]'),
service = new google.maps.places
.PlacesService(document.createElement('div'));
for (var i = 0; i < photos.length; ++i) {
(function(photo) {
service.getDetails({
placeId: photo.getAttribute('data-place')
}, function(r) {
if (r.photos.length) {
google.maps.event.addDomListener(photo, 'click', function() {
photo.setAttribute('src', r.photos[0].getUrl({
maxHeight: 100
}));
photo.style.visibility = 'visible';
if (r.photos.length > 1) {
r.photos.push(r.photos.shift());
photo.setAttribute('title', 'click to see next photo');
photo.style.cursor = 'pointer';
} else {
google.maps.event.clearListeners(photo, 'click');
}
});
google.maps.event.trigger(photo, 'click');
}
});
}(photos[i]));
}
}
body::before {
content: url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-white2.png);
}
img[data-place] {
visibility: hidden;
display: block;
}
<ul>
<li>
Google: Mountain View
<img data-place="ChIJj61dQgK6j4AR4GeTYWZsKWw" />
</li>
<li>
Google: Sydney
<img data-place="ChIJN1t_tDeuEmsRUsoyG83frY4" />
</li>
<li>
Google: Berlin
<img data-place="ChIJReW1rcRRqEcRaY3CuKBdqZE" />
</li>
</ul>
<script defer src="https://maps.googleapis.com/maps/api/js?v=3&libraries=places&callback=loadPlacePhotos"></script>
该演示使用图像 data-place
的自定义属性,该属性将分配给特定地点的 placeId
。它解析这些图像,请求照片并显示它们(当有超过 1 张照片时,用户可以通过单击图像在照片之间切换)
但是,当您的密钥可见时,这一定不是问题,为您的(浏览器)密钥设置允许的引荐来源网址,您可以在您自己的域中毫无风险地使用该密钥。
我正在尝试使用 php 为我的网站呈现图像,该图像将直接动态显示来自 Google 地点 API 的图像(参考 https://developers.google.com/places/web-service/photos?hl=en) 图像源类似于以下示例:
https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=CnRtAAAATLZNl354RwP_9UKbQ_5Psy40texXePv4oAlgP4qNEkdIrkyse7rPXYGd9D_Uj1rVsQdWT4oRz4QrYAJNpFX7rzqqMlZw2h2E2y5IKMUZ7ouD_SlcHxYq1yL4KbKUv3qtWgTK0A6QbGh87GB3sscrHRIQiG2RrmU_jF4tENr9wGS_YxoUSSDrYjWmrNfeEHSGSc3FyhNLlBU&key=API_KEY
如果您通过浏览器访问此 URL,它将呈现一个图像,这不再是您看到的 URL。
我的问题是,当查看页面源时,这正是您看到的图像源 URL,这是错误的,因为我的密钥随后被公开了。在保持我的密钥私密性的同时呈现图像的正确方法是什么?我为此在 API 和网上进行了搜索,但无济于事。我确实看到了一些使用 file_get_contents 和 file_put_contents 的技巧,但我的虚拟主机不允许这样做。最后,保存图像违反了 api 规则,所以这不是一个选项。
如有任何提示,我们将不胜感激。提前致谢。
您可以向特定的 URL 发送 HEAD 请求并提取 Location
-header 的内容:
<?php
$context = stream_context_create(array('http' =>array('method'=>'HEAD')));
$fp = fopen('desiredPlacesApiImgUrl', 'rb', false, $context);
$meta = stream_get_meta_data($fp);
if(isset($meta['wrapper_data'])){
$location=preg_grep('@^\s*Location:@',$meta['wrapper_data']);
if(count($location)){
$imgUrl=trim(preg_replace('@^Location:@i','',reset($location)));
die($imgUrl);//the desired img-url
}
}
fclose($fp);
?>
但是当你的服务器上不允许 file_get_contents
恐怕 fopen
也不允许外部 URLs.
另一种选择:使用地图-Javascript-API,请求地点,响应应包含所需的URL(不使用任何键)。
演示:
function loadPlacePhotos() {
var photos = document.querySelectorAll('img[data-place]'),
service = new google.maps.places
.PlacesService(document.createElement('div'));
for (var i = 0; i < photos.length; ++i) {
(function(photo) {
service.getDetails({
placeId: photo.getAttribute('data-place')
}, function(r) {
if (r.photos.length) {
google.maps.event.addDomListener(photo, 'click', function() {
photo.setAttribute('src', r.photos[0].getUrl({
maxHeight: 100
}));
photo.style.visibility = 'visible';
if (r.photos.length > 1) {
r.photos.push(r.photos.shift());
photo.setAttribute('title', 'click to see next photo');
photo.style.cursor = 'pointer';
} else {
google.maps.event.clearListeners(photo, 'click');
}
});
google.maps.event.trigger(photo, 'click');
}
});
}(photos[i]));
}
}
body::before {
content: url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-white2.png);
}
img[data-place] {
visibility: hidden;
display: block;
}
<ul>
<li>
Google: Mountain View
<img data-place="ChIJj61dQgK6j4AR4GeTYWZsKWw" />
</li>
<li>
Google: Sydney
<img data-place="ChIJN1t_tDeuEmsRUsoyG83frY4" />
</li>
<li>
Google: Berlin
<img data-place="ChIJReW1rcRRqEcRaY3CuKBdqZE" />
</li>
</ul>
<script defer src="https://maps.googleapis.com/maps/api/js?v=3&libraries=places&callback=loadPlacePhotos"></script>
该演示使用图像 data-place
的自定义属性,该属性将分配给特定地点的 placeId
。它解析这些图像,请求照片并显示它们(当有超过 1 张照片时,用户可以通过单击图像在照片之间切换)
但是,当您的密钥可见时,这一定不是问题,为您的(浏览器)密钥设置允许的引荐来源网址,您可以在您自己的域中毫无风险地使用该密钥。