解决:php
看我把这些坑都总结了一下:要命的invalid signature。css
https://segmentfault.com/q/1010000002520634html
有人这样说:json
出现问题的缘由是参与签名的URL地址不正确,须要动态获取当前页面完整的URL地址(包括?后面的参数,但不能包含#号),如若URL地址为:http://www.xxx.xxx/payment/wxpay/jspay?oid=xxxx&attr=xxxx#wechat,那么完整的URL地址应该是截取#号以前的部份。为何会出现#号呢?由于你的URL在被分享到朋友圈等微信系统自动会添加一些参数。segmentfault
invalid signature出现可能还有其余缘由的api
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign安全
示例代码:服务器
http://203.195.235.76/jssdk/#menu-voice微信
http://demo.open.weixin.qq.com/jssdk/sample.zipapp
经对比,微信 JS 接口签名校验正确,往下走
sample.php
<?php
require_once "jssdk.php";
$jssdk = new JSSDK("appid", "ssss");
$signPackage = $jssdk->GetSignPackage();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<link rel="stylesheet" href="http://203.195.235.76/jssdk/css/style.css">
<body>
appId: '<?php echo $signPackage["appId"];?>
<br>
timestamp: <?php echo $signPackage["timestamp"];?>
<br>
nonceStr: '<?php echo $signPackage["nonceStr"];?>
<br>
$ticket:<?php echo $ticket; ?>
<br>
<?php echo $signPackage["signature"];?>
<br>
<button class="btn btn_primary" id="startRecord">startRecord</button>
</body>
<button class="btn btn_primary" id="stopRecord">stopRecord</button>
<button class="btn btn_primary" id="playVoice">playVoice</button>
<button class="btn btn_primary" id="pauseVoice">pauseVoice</button>
<button class="btn btn_primary" id="stopVoice">stopVoice</button>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script>
/*
* 注意:
* 1. 全部的JS接口只能在公众号绑定的域名下调用,公众号开发者须要先登陆微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
* 2. 若是发如今 Android 不能分享自定义内容,请到官网下载最新的包覆盖安装,Android 自定义分享接口需升级至 6.0.2.58 版本及以上。
* 3. 常见问题及完整 JS-SDK 文档地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html
*
* 开发中遇到问题详见文档“附录5-常见错误及解决办法”解决,如仍未能解决可经过如下渠道反馈:
* 邮箱地址:weixin-open@qq.com
* 邮件主题:【微信JS-SDK反馈】具体问题
* 邮件内容说明:用简明的语言描述问题所在,并交代清楚遇到该问题的场景,可附上截屏图片,微信团队会尽快处理你的反馈。
*/
wx.config({
debug: true,
appId: '<?php echo $signPackage["appId"];?>', timestamp: <?php echo $signPackage["timestamp"];?>, nonceStr: '<?php echo $signPackage["nonceStr"];?>', signature: '<?php echo $signPackage["signature"];?>', jsApiList: [ // 全部要调用的 API 都要加到这个列表中 'checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone', 'hideMenuItems', 'showMenuItems', 'hideAllNonBaseMenuItem', 'showAllNonBaseMenuItem', 'translateVoice', 'startRecord', 'stopRecord', 'onVoiceRecordEnd', 'playVoice', 'onVoicePlayEnd', 'pauseVoice', 'stopVoice', 'uploadVoice', 'downloadVoice', 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage', 'getNetworkType', 'openLocation', 'getLocation', 'hideOptionMenu', 'showOptionMenu', 'closeWindow', 'scanQRCode', 'chooseWXPay', 'openProductSpecificView', 'addCard', 'chooseCard', 'openCard' ] }); wx.ready(function () { // 在这里调用 API // 4 音频接口 // 4.2 开始录音 document.querySelector('#startRecord').onclick = function () { wx.startRecord({ cancel: function () { alert('用户拒绝受权录音'); } }); }; // 4.3 中止录音 document.querySelector('#stopRecord').onclick = function () { wx.stopRecord({ success: function (res) { voice.localId = res.localId; }, fail: function (res) { alert(JSON.stringify(res)); } }); }; // 4.4 监听录音自动中止 wx.onVoiceRecordEnd({ complete: function (res) { voice.localId = res.localId; alert('录音时间已超过一分钟'); } }); // 4.5 播放音频 document.querySelector('#playVoice').onclick = function () { if (voice.localId == '') { alert('请先使用 startRecord 接口录制一段声音'); return; } wx.playVoice({ localId: voice.localId }); }; // 4.6 暂停播放音频 document.querySelector('#pauseVoice').onclick = function () { wx.pauseVoice({ localId: voice.localId }); }; // 4.7 中止播放音频 document.querySelector('#stopVoice').onclick = function () { wx.stopVoice({ localId: voice.localId }); }; // 4.8 监听录音播放中止 wx.onVoicePlayEnd({ complete: function (res) { alert('录音(' + res.localId + ')播放结束'); } }); // 4.8 上传语音 document.querySelector('#uploadVoice').onclick = function () { if (voice.localId == '') { alert('请先使用 startRecord 接口录制一段声音'); return; } wx.uploadVoice({ localId: voice.localId, success: function (res) { alert('上传语音成功,serverId 为' + res.serverId); voice.serverId = res.serverId; } }); }; // 4.9 下载语音 document.querySelector('#downloadVoice').onclick = function () { if (voice.serverId == '') { alert('请先使用 uploadVoice 上传声音'); return; } wx.downloadVoice({ serverId: voice.serverId, success: function (res) { alert('下载语音成功,localId 为' + res.localId); voice.localId = res.localId; } }); }; });</script></html>
jssdk.php
<?php class JSSDK { private $appId; private $appSecret; public function __construct($appId, $appSecret) { $this->appId = $appId; $this->appSecret = $appSecret; } public function getSignPackage() { $jsapiTicket = $this->getJsApiTicket(); // 注意 URL 必定要动态获取,不能 hardcode. $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; $timestamp = time(); $nonceStr = $this->createNonceStr(); // 这里参数的顺序要按照 key 值 ASCII 码升序排序 $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url"; $signature = sha1($string); $signPackage = array( "appId" => $this->appId, "nonceStr" => $nonceStr, "timestamp" => $timestamp, "url" => $url, "signature" => $signature, "rawString" => $string ); return $signPackage; } private function createNonceStr($length = 16) { $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $str = ""; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } private function getJsApiTicket() { // jsapi_ticket 应该全局存储与更新,如下代码以写入到文件中作示例 $data =123; if ($data) { $accessToken = $this->getAccessToken(); // 若是是企业号用如下 URL 获取 ticket //$url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken"; $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken"; $res = json_decode($this->httpGet($url)); $ticket = $res->ticket; if ($ticket) { $data->expire_time = time() + 7000; $data->jsapi_ticket = $ticket; $this->set_php_file("jsapi_ticket.php", json_encode($data)); } } else { $ticket = $data->jsapi_ticket; } // print_r(1232); return $ticket; } private function getAccessToken() { // access_token 应该全局存储与更新,如下代码以写入到文件中作示例 $data = 12333; if ($data) { // 若是是企业号用如下URL获取access_token // $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret"; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret"; $res = json_decode($this->httpGet($url)); print_r($res); $access_token = $res->access_token; if ($access_token) { $data->expire_time = time() + 7000; $data->access_token = $access_token; $this->set_php_file("access_token.php", json_encode($data)); } } else { $access_token = $data->access_token; } echo 'access+token:'.$access_token."<br>"; return $access_token; } private function httpGet($url) { $curl = curl_init(); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_TIMEOUT, 500); // 为保证第三方服务器与微信服务器之间数据传输的安全性,全部微信接口采用https方式调用,必须使用下面2行代码打开ssl安全校验。 // 若是在部署过程当中代码在此处验证失败,请到 http://curl.haxx.se/ca/cacert.pem 下载新的证书判别文件。 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true); curl_setopt($curl, CURLOPT_URL, $url); $res = curl_exec($curl); curl_close($curl); return $res; } private function get_php_file($filename) { return trim(substr(file_get_contents($filename), 15)); } private function set_php_file($filename, $content) { $fp = fopen($filename, "w"); fwrite($fp, "<?php exit();?>" . $content); fclose($fp); } }
在正常空间服务器上运行成功,免费空间原来httpGet获取时return返回值为空对比。.服务器空间问题1.gunner.site(主题屋免费空间php curl调用https出错
)2.正规服务器(无提示错误)3.本地可打印access_token
解决办法:跳过SSL证书检查。
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
哈哈,有开始出现新问题require subscribe,由于我用公众平台测试账号,关注一下就好

关注就能够


调用微信JS-SDK 接口成功
微信公众平台开发者文档