前言:在作微信公众号开发时须要获取用户的地理位置信息,以前经过高德或者百度、腾讯等地图的api时发现常常获取不到,毕竟第三方的东西,后来改成采用微信内置的js-sdk中的获取地理位置接口,在这主要记录下签名的获取(麻烦点)和一个获取地理位置的例子。javascript
<!--引入js-sdk--> <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script> <!--点击图标触发事件--> <img onclick="getCurrentLocation()" src="__PUBLIC__/img/gap.png"> //根据微信js-sdk内置接口 getCurrentLocation function getCurrentLocation(){ //这个是获取签名时的url,动态变化,因此在前段获取,后端传入直接使用 var url = location.href.split('#')[0]; var ajaxUrl = '/*****/getWxsdkSign'; //ajax异步获取微信签名sign $.get(ajaxUrl, {url : url}, function(json){ if(json.code == 0){ let sdkSign = json.data; // 后台返回的值 wx.config({ debug: false, // ture会alert所有信息,上线时改成false appId: sdkSign.appId, // 必填,公众号惟一标识 timestamp: sdkSign.timestamp, // 必填,生成签名的时间戳 nonceStr: sdkSign.nonceStr, // 必填,生成签名的随机串 signature: sdkSign.signature,// 必填,签名 jsApiList: ['getLocation',] // 必填,须要调用的接口列表,本需求里只是获取位置信息,具体的接口名称查阅js-sdk文档 }); //获取地理位置(经纬度) wx.getLocation({ type: 'gcj02', // 默认为wgs84的gps坐标,若是要返回直接给openLocation用的火星坐标,可传入'gcj02' success: function (res) { var latitude = res.latitude; //纬度,浮点数 var longitude = res.longitude; //经度,浮点数 //如下这部份内容就是再经过异步操做逆地理编码获取真实的地址信息 getLocationBylatlng(latitude, longitude); } }); }else{ //TODO 获取签名失败的处理,未获取到地理位置 ***************** ***************** } },'json'); }
/*---------------------------------获取js-sdk签名 start--------------------------------*/ /** * 获取js-sdk调用权限,获取签名 */ public function getWxsdkSign(){ $appId = $this->appid; //这里填appid $appsecret = $this->appsecret; //这里填appsecret //通常$url是固定的,能够写死,可是个人项目中地址是动态的,因此由前段传入 $url = I('get.url'); //获取签名的页面的url地址,因为是动态地址,因此由前段传入 // 获取accesstoken $accessToken = $this->getAccessToken(); if(empty($accessToken)){ $this->ajaxReturn(['code'=>-1, 'msg'=>'accessToken未获取到']); } // 获取jsapi_ticket $jsapi_ticket = $this->_getJsapiTicket($accessToken); if(empty($jsapi_ticket)){ $this->ajaxReturn(['code'=>-1, 'msg'=>'jsapi_ticket未获取到']); } $nonceStr = $this->make_nonceStr(); //获取随机字符串 $timestamp = time(); $signature = $this->make_signature($nonceStr,$timestamp,$jsapi_ticket,$url); $sdkSign = array( 'appId' => $this->appid, //appid 'signature' => $signature, //签名 'timestamp' => $timestamp, //时间戳 'nonceStr' => $nonceStr, //随机字符串 ); $this->ajaxReturn(['code'=>0, 'data'=>$sdkSign]); } /** * 此AccessToken 与 getUserAccessToken不同,注意一下定要全局缓存,不然每日次数限制很快就GG了 * 得到AccessToken */ private function getAccessToken() { //获取缓存(我用的是本身封装的Memcached类,Vender引入的直接使用) Vendor('Memcacheds.Memcacheds'); $memcached = new \Memcacheds(); $access = $memcached->get_cache('access_token'); // 缓存不存在-从新建立 if (empty($access)) { // 获取 access token $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this -> appid}&secret={$this->appsecret}"; $accessToken = file_get_contents($url); $accessToken = json_decode($accessToken); // 保存至缓存 $access = $accessToken->access_token; $memcached->set_cache('access_token', $access, 7000); } return $access; } /** * 获取JS证实 注意一下定要全局缓存,不然每日次数限制很快就GG了 * @param $accessToken */ private function _getJsapiTicket($accessToken) { Vendor('Memcacheds.Memcacheds'); $memcached = new \Memcacheds(); //获取缓存 $ticket = $memcached->get_cache('jsapi_ticket'); //缓存不存在-从新建立 if (empty($ticket)) { // 获取js_ticket $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" . $accessToken . "&type=jsapi"; $jsTicket = file_get_contents($url); $jsTicket = json_decode($jsTicket); //保存至缓存 $ticket = $jsTicket->ticket; $memcached->set_cache('jsapi_ticket', $ticket, 7000); } return $ticket; } //获取随机字符串 public function make_nonceStr(){ $codeSet = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; for ($i = 0; $i<16; $i++) { $codes[$i] = $codeSet[mt_rand(0, strlen($codeSet)-1)]; } $nonceStr = implode($codes); return $nonceStr; } /** * 获取签名 * @param string $nonceStr 随机字符串 * @param int $timestamp 时间戳 * @param string $jsapi_ticket 获取的ticket凭据 * @param string $url 获取签名的页面的url 'http://*****' eg:'http://wx.alisleept.top/index.php' */ function make_signature($nonceStr,$timestamp,$jsapi_ticket,$url){ $tmpArr = array( 'noncestr' => $nonceStr, 'timestamp' => $timestamp, 'jsapi_ticket' => $jsapi_ticket, 'url' => $url ); ksort($tmpArr, SORT_STRING); $string1 = http_build_query( $tmpArr ); $string1 = urldecode( $string1 ); $signature = sha1( $string1 ); return $signature; } /*---------------------------------获取js-sdk签名 end--------------------------------*/
以上php部分就是彻底的异步获取签名的代码,里边只须要注意php