前言:在作微信公衆號開發時須要獲取用戶的地理位置信息,以前經過高德或者百度、騰訊等地圖的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