昨天,想到给本博客的日记加个发布地址。于是想到了两个办法:
- 后端实现,通过发布日记的客户端外网IP,查找IP分享服务器查找 改IP的地理位置
- 前端实现,利用html5的新特性之一(地理位置 Geolocation)
据我之前的对这两种方法的探究,有以下印象:
- 通过IP分享服务器查找相对应的地理位置的成功率是很高的
但是精度不咋地,一般只能定位到市,eg:(广东省广州市 电信) 额外能查到网络提供商- 通过html5能定位到相对更高精度的地理位置,细到门牌号,甚至第几楼(ps:不准确)
但是这方式的定位成功率不高- 另外,html5定位需要授权,外网IP不需要,但外网IP可以被伪装
考虑了下, 还是决定用html5的新特性。
后来发现在台式电脑上,定位成功率略低,不同浏览器定位成功率也不一样。
在台式电脑调试中,我居然发现chrome浏览器定位成功率很低,IE的成功率高多了,出乎我意外
再后来,做了优化,在html5失败的情况下,通过外网IP去定位做下补救。
php通过IP获取地理位置:
$ip = $request->get('ip'); if (!$ip){ $ip = $request->ip(); } //通过ip.cn获取地理位置 $curl = new MyCurl(); $curl->url = "http://www.ip.cn/index.php?ip={$ip}"; $curl->header = ['User-Agent:curl/7.29.0']; $result = $curl->request(); $match = []; preg_match('/来自:(\S*)/', $result['result'], $match); $address = isset($match[1]) ? $match[1] : "unknown"; echo $address;
前端h5获取地理位置(h5获取经纬度,通过百度jsapi获取具体地理位置):
<script src="https://api.map.baidu.com/api?v=2.0&ak=xyLg35B5IHOZ8x86EZLR6bRXAlUn4iHa&s=1"></script> <script> function getaddress(){ $.ajax({ async:true, type:'get', url:"{{ route('api.ip') }}", cache:false, timeout:5000,//毫秒 data:{ }, beforeSend:function(){ $("#address").val($("#address").val() + ";正在向服务器请求定位..."); }, error:function(){ $("#address").val("sorry,定位彻底失败!"); }, success:function(ret){ $("#address").val(ret); } }); } //console.log(navigator.geolocation); if (navigator.geolocation) { //setTimeout("console.log('ip location')", 3000 ); navigator.geolocation.getCurrentPosition(function (position) { console.log(position); var lat = position.coords.latitude; var lon = position.coords.longitude; var point = new BMap.Point(lon, lat); // 创建点坐标 var gc = new BMap.Geocoder(); gc.getLocation(point, function (rs) { var addComp = rs.addressComponents; $("#address").val(addComp.province + addComp.city + addComp.district + addComp.street + addComp.streetNumber); }); }, function (error) { console.log(error); var err = "获取失败:"; switch (error.code) { case 1: err += "位置服务被拒绝。"; break; case 2: err += "暂时获取不到位置信息。"; break; case 3: err += "获取位置信息超时。"; break; default: err += "未知错误。"; break; } $("#address").val(err); getaddress(); }, { timeout: 5000, enableHighAccuracy: true }); } else { $("#address").val("你的浏览器不支持获取地理位置信息。"); getaddress(); } $('.biaoqing').click(function(){ $('#content').insertContent(' {'+$(this).attr('title')+'} '); }); </script>