【问题标题】:Google Places APi photoGoogle Places APi 照片
【发布时间】:2015-09-06 07:20:04
【问题描述】:

我正在尝试使用 php 为我的网站呈现图像,该图像将直接从 Google Places 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 规则的,所以这不是一种选择。

任何提示将不胜感激。提前致谢。

【问题讨论】:

    标签: php google-maps google-places-api


    【解决方案1】:

    您可以向特定 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 时,恐怕外部 URL 也不允许使用 fopen

    另一种选择:使用 Maps-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 张照片时,用户可以通过单击图像在照片之间切换)


    但是,当您的密钥可见时,这一定不是问题,为您的(浏览器)密钥设置允许的引用者,您就可以在自己的域上使用该密钥而没有风险。

    【讨论】:

    • fopen:你是对的,也不能使用 fopen。然而,伟大的想法。您对使用 JavaScript 的建议非常有效。我将不得不找到一种修改它的方法,以便图像在鼠标悬停时以一段时间间隔改变,但这绝对符合我的目的 - 谢谢!最后,虽然我的密钥在我解释的场景中可见是可以的,但具有未使用我的 API 密钥注册的 ip 地址的机器根本不会显示图像,而是显示占位符(实际上是所有访问者)。由于我的动态IP,即使我自己也受到影响。再次感谢您的时间和彻底性,已解决。
    • 我已经修复了(将延迟属性添加到 maps-API)
    • 谢谢你。最后一个问题,因为我不精通 JS。我怎样才能做到这一点,而不是必须单击图像标签来查看下一张照片,我可以将鼠标悬停在它上面,每隔 x 秒它就会循环到下一张?我已经将“点击”替换为“鼠标悬停”,但想要一个计时器来启动并在鼠标仍然悬停在图像上时更改图像。提前谢谢你。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    • 2015-10-08
    • 2019-01-24
    • 2021-01-13
    • 1970-01-01
    相关资源
    最近更新 更多