定期更新通过 cURL 请求从 API 获取的地理位置数据

Posted

技术标签:

【中文标题】定期更新通过 cURL 请求从 API 获取的地理位置数据【英文标题】:Updating geolocation data, gotten from an API through a cURL request, at a timed interval 【发布时间】:2019-10-27 15:40:21 【问题描述】:

我通过带有 cURL 请求的 API 获得两个值(纬度、经度)。我的请求如下所示:

function APIcall($method, $url, $data)
   $curl = curl_init();

   switch ($method)
      case "POST":
         curl_setopt($curl, CURLOPT_POST, 1);
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
         break;
      case "PUT":
         curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);                              
         break;
      default:
         if ($data)
            $url = sprintf("%s?%s", $url, http_build_query($data));
   

   // OPTIONS:
   curl_setopt($curl, CURLOPT_URL, $url);
   curl_setopt($curl, CURLOPT_HTTPHEADER, array(
      'APIKEY: example-key-here',
      'Content-Type: application/json',
   ));
   curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

   // EXECUTE:
   $result = curl_exec($curl);
   if(!$result)die("Connection Failure");
   curl_close($curl);
   return $result;


$get_data = APIcall('GET', 
'https://api.wheretheiss.at/v1/satellites/25544', false);
$response = json_decode($get_data, true);

此调用位于我的根文件夹中的单独文件apicall.php 中,然后我可以有效地将其包含在我需要的位置。当我这样做时,我使用$response 变量中给我的值来回显纬度和经度的值,这正是我需要的:

echo $response['latitude'];
echo $response['longitude'];

我在我的 Leaflet.js 地图的脚本标记内执行此操作,以在其上放置一个标记,位于 API 提供的坐标处:

mymap.setView([<?php echo $response['latitude']; ?>, <?php echo $response['longitude']; ?>], mymap.getZoom());  
marker.setLatLng([<?php echo $response['latitude']; ?>, <?php echo $response['longitude']; ?>]);

这就是我的问题出现的地方。我上面的代码只放置一次标记,因为调用只进行一次(当然)。我将如何在不重新加载整个页面的情况下定期拨打更多电话?

【问题讨论】:

使用 ajax 将请求发送到后端脚本,然后将请求发送到 API 是一种选择 - 使用计时器设置它相当简单 @RamRaider 我试过这样的事情:function repeatAjax() $.ajax( type: "GET", url: 'apicall.php', success: function(resp) console.log("Success"); , complete: function() setTimeout(repeatAjax,5000); ); 我错过了什么? 【参考方案1】:

如果您在查看 API 端点时查看响应标头,您应该会注意到它们有 Access-Control-Allow-Origin: *,这意味着您可以直接从 javascript 发出 HttpRequest。您可以使用 Ajax 或 Fetch 来执行此操作 - 在下文中,我选择了 Fetch,因为使用此 API 是一项非常简单的任务。毫无疑问,可以直接从 jQuery 中获得类似的选项,但由于我不使用它,所以我无法建议,当您查看代码时,您会发现在这种情况下也没有真正需要使用它。 由于 API 已向所有来源公开,因此确实不需要 curl 请求!

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>Where is the ISS?</title>
        <script>
            document.addEventListener('DOMContentLoaded',()=>
                /* api endpoint */
                let url='https://api.wheretheiss.at/v1/satellites/25544';

                /* only for demo purposes - display output in this element */
                let out=document.querySelector('output');

                /* ultra simple callback to display data from API */
                const callback=function( r )
                    out.innerText=Object.keys(r).map( ( k )=>
                        return [ k, r[ k ] ].join( ':' )
                    ).join( String.fromCharCode( 10 ) )
                ;

                /* Send a basic request to the api ( which returns JSON ) and process using callback */
                const fetchposition=function( url, callback )
                    fetch( url ).then( r=> return r.json()  ).then( callback )
                ;

                /* 
                    create a self-executing anonymous function with relevant 
                    parameters ~ this is in the John Resig style... 

                    This acts like `setInterval` or a self referencing `setTimeout`

                */
                (function( url, delay, callback )
                    (function()
                        setTimeout( arguments.callee, 1000 * delay );
                        fetchposition( url, callback );
                    )();
                )( url, 5, callback );             
            );
        </script>
    </head>
    <body>
        <output></output>
    </body>
</html>

一次迭代的示例数据:

name:iss
id:25544
latitude:34.995889522375
longitude:129.28250031522
altitude:422.37051205509
velocity:27577.33696572
visibility:eclipsed
footprint:4519.5039529858
timestamp:1572204467
daynum:2458784.3109606
solar_lat:-12.881716643173
solar_lon:244.02703108844
units:kilometers

从此应该可以轻松修改地图上标记的位置 - 或为每个结果添加新标记...


以下关于 PHP 代码顶部的 actual api ~ 的评论使用 curl 发送 API 请求。

<?php
    if($_SERVER['REQUEST_METHOD']=='POST' && !empty( $_POST['query'] ) )
        ob_clean();
        # send api request ~ using cURL, carrier pigeon or whatever
        exit( date( DATE_ATOM ) );
    
?>
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>Where is the ISS?</title>
        <script>
            document.addEventListener('DOMContentLoaded',()=>

                let out=document.querySelector('output');

                const ajaxcallback=function(r)
                    let div=document.createElement('div');
                        div.innerText=r;
                    out.appendChild( div ); 
                ;
                const ajax=function(url,params,callback)
                    let xhr=new XMLHttpRequest();
                        xhr.onload=function()
                            if( this.status==200 && this.readyState==4 )callback( this.response )
                        ;
                        xhr.open( 'POST', url, true );
                        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                        xhr.send( params );
                ;


                (function( url, delay, callback )
                    (function()
                        setTimeout( arguments.callee, 1000 * delay );
                        ajax( url, 'query=api', callback )
                    )();
                )( 'apicall.php', 5, ajaxcallback );               
            );

        </script>
    </head>
    <body>
        <output></output>
    </body>
</html>

【讨论】:

感谢您的努力。我很抱歉,但我应该指定。我会这样做,这本来会简单得多,但是我使用的实际 API 要求我在 URL 中传递一个密钥,我认为展示它并不是一件好事在生产环境的客户端。对不起!

以上是关于定期更新通过 cURL 请求从 API 获取的地理位置数据的主要内容,如果未能解决你的问题,请参考以下文章

我可以从仅通过城市的 Google Geocoding API 获取地理编码信息吗?

Bitbucket API 更新管道变量

Spotify:发布到 api/token 给出了错误的请求,但在 curl 中工作

如何从 curl 请求中获取响应时间(通过命令行)

使用手机信号塔信息的谷歌地理定位 - Curl 400 Bad request PHP

使用 CURL 的所有酒店位置的 Skyscanner API