今天應客戶要求,把一個html5遊戲的微信分享功能從第三方庫切換到官方庫了,官方微信JSSDK。
這其中碰到了一些問題,記錄一下(服務端環境爲PHP):javascript
###1. 開啓openssl功能php
Warning: file_get_contents(https://graph.qq.com/user/xxxxx) [function.file-get-contents]: failed to open stream: No error in /xxx/php.php on line 2
遇到這樣的錯誤的,是由於沒有開啓openssl
功能,能夠在php.ini中把 extension=php_openssl.dll
以前的;
去掉,保存並重啓(最好重啓服務器)html
注意:
php.ini
的位置是在phpinfo中找的。html5
###2. encodeURIComponent(url) js端的要記得把當前頁面的url編碼,否則送給服務器的參數可能不對,最後致使簽名出錯。java
####最後附上相關的源碼,包括服務端和javascript:python
/** * Author: lonewolf * Date: 2015-02-08 13:48:43 */ // 微信分享的數據 var wxData = { title : '好玩的遊戲!', desc : '你們快來玩!', link : 'http://xxx', imgUrl : 'http://xxx.png', type: '', dataUrl: '', success: function () { //分享成功 //do something! } }; // 配置數據 wxConfigData={ debug: true, //調試的時候最好設爲true,它每一步都會alert數據出來,讓你知道出了什麼問題 appId: 'xxx', timestamp: 1423367602, //隨便填寫一串數字 nonceStr: 'sMADlDUaGt6DsEc6', //隨便一字符串 signature: '', //**這個要到服務器獲取** jsApiList: [ //用到的功能,自定義 'checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo' ] } // 獲取簽名 function wxGetSign () { var data1={}; data1["timestamp"]=wxConfigData["timestamp"]; data1["nonceStr"]=wxConfigData["nonceStr"]; data1["url"]=encodeURIComponent(location.href.split('#')[0]); // alert(data1["url"]); // 本身找個ajax庫 ajax.post("wxGetSign.php?ran="+Math.random(), data1, function (data) { // 返回{sign:xxx} // alert(data); data=eval("("+data+")"); if(data["sign"]) { // 獲取簽名成功,初始化分享 wxConfigData["signature"]=data["sign"]; wxInit(); } }); } // 初始化,已經得到簽名 function wxInit () { // 配置參數 wx.config(wxConfigData); // 分享 wx.ready(function(){ addWeixinShareListening(); }); wx.error(function(res){ // alert(res); }); } // 分享綁定 function addWeixinShareListening () { wx.onMenuShareTimeline(wxData); wx.onMenuShareAppMessage(wxData); wx.onMenuShareQQ(wxData); wx.onMenuShareWeibo(wxData); } //執行,獲取簽名 wxGetSign();
相關的參數改一改,放到頁面中就能夠了,也可保存爲一個js文件。ajax
<?php /* 由於獲取的access_token以及jsapi_ticket都有時間限制(7200秒後失效),且調用接口的次數有限制,因此咱們得把獲得的access_token和jsapi_ticket緩存到一個文件裏,每次請求都檢查是否已過時。 */ //設置時區 date_default_timezone_set('Asia/ShangHai'); //session session_start(); $returnObj = array("sign" => ""); // 常量 $appId="xxx"; $appSecret="xxx"; $timestamp = $_POST["timestamp"]; $nonceStr = $_POST["nonceStr"]; $url = $_POST["url"]; if ($timestamp&&$nonceStr&&$url) { // 獲取access_token和jsapi_ticket $access_token=""; $jsapi_ticket=""; // 保存到文件sign.txt $filename="sign.txt"; $time=time(); // 先查找本地有沒有保存 if (file_exists($filename)) { $str=file_get_contents($filename); $obj=json_decode($str,true); if ($obj&&$obj["access_token"]&&$obj["jsapi_ticket"]&&$obj["time"]) { $lastTime=intval($obj["time"]); // 標準的是7200,要少一點 if ($time-$lastTime<7100) { $access_token=$obj["access_token"]; $jsapi_ticket=$obj["jsapi_ticket"]; } } } if ($access_token=="") { // 若是第一次或已過時則從新獲取 $returnObj["re"]=1; //這個只是測試用,看看是否是新請求 // 獲取access_token $tokenUrl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}"; $str=file_get_contents($tokenUrl); // $returnObj["token_data"]=$str; $obj=json_decode($str,true); if ($obj&&$obj["access_token"]) { $access_token=$obj["access_token"]; // 獲取jsapi_ticket $ticketUrl="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$access_token}&type=jsapi"; $str=file_get_contents($ticketUrl); // $returnObj["ticket_data"]=$str; $obj=json_decode($str,true); if ($obj&&$obj["errcode"]==0&&$obj["ticket"]) { $jsapi_ticket=$obj["ticket"]; // 保存文件 $data=array("access_token"=>$access_token,"jsapi_ticket"=>$jsapi_ticket,"time"=>$time); $data=json_encode($data); file_put_contents($filename, $data); } else { $returnObj["error"]="wrong ticket"; } } else { $returnObj["error"]="wrong access_token"; } } if ($access_token&&$jsapi_ticket) { // test // $returnObj["access_token"]=$access_token; // $returnObj["jsapi_ticket"]=$jsapi_ticket; // 簽名算法 $str="jsapi_ticket={$jsapi_ticket}&noncestr={$nonceStr}×tamp={$timestamp}&url={$url}"; // $returnObj["signstr"]=$str; $sign=sha1($str); $returnObj["sign"]=$sign; } } echo json_encode($returnObj); ?>
至此,整個過程就算完了。算法