🎈 微信 JS-SDK
- 微信 JS-SDK 是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包
- 通过使用微信
JS-SDK
,开发者可借助微信高效地使用拍照
、选图
、语音
、位置
等手机系统的能力 - 同时可以直接使用
微信分享
、扫一扫
、卡券
、支付
等微信特有的能力,是管理微信一切生态的API
🎈 JS-SDK 使用步骤
- 绑定域名: 需要在微信公众平台
公众号设置
的功能设置
里填写JS接口安全域名
- 引入 JS 文件: 要使用
JS-SDK
的接口,需要引入http://res.wx.qq.com/open/js/jweixin-1.6.0.js
- 注入配置: 所有需要使用
JS-SDK
的页面必须先注入配置信息,否则将无法调用 - 配置验证成功后的回调:
config
信息验证后会执行ready
方法 - 配置验证失败后的回调:
config
信息验证失败会执行error
函数,如签名过期导致验证失败
wx.config({ debug: true, // 开启调试模式,调用的所有 api 的返回值会在客户端 alert 出来,若要查看传入的参数,可以在 pc 端打开,参数信息会通过 log 打出,仅在 pc 端时才会打印。appId: '', // 必填,公众号的唯一标识timestamp: , // 必填,生成签名的时间戳nonceStr: '', // 必填,生成签名的随机串signature: '',// 必填,签名jsApiList: [] // 必填,需要使用的 JS 接口列表}); wx.ready(function(){ // 成功后的回调,所有接口调用都必须在 config 接口获得结果之后}); wx.error(function(res){ // 失败后的回调});
🎈 JS-SDK 签名生成
- 由上面可知道,如果想要调用
JS-SDK
的接口,必须是在wx.config
验证成功之后才可以 - 而
wx.config
里面最重要的就是JS-SDK
签名中的一些参数 - 点击可下载 官方SDK示例,
SDK
其中包含php
、java
、nodejs
以及python
的示例代码,其中就有封装好的JS-SDK
签名生成类 - 我们这里以
php
签名生成类来讲解,前端使用JS-SDK
接口,必须就调用其中的getSignPackage
方法,生成签名包,然后将包里面的参数,传到wx.config
中即可 - 在
getSignPackage
中,可以看到需要生成jsapiTicket
标识,而这个标识需要通过access_token
获取 - 然后将获取到的
jsapiTicket
标识与请求url
、时间戳
、随机字符串
等进行加密形成签名后一起返回给前端即可,可以参考 JS-SDK使用权限签名算法
classJSSDK{ private$appId; private$appSecret; publicfunction__construct($appId, $appSecret) { $this->appId=$appId; $this->appSecret=$appSecret; } publicfunctiongetSignPackage() { $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; } privatefunctioncreateNonceStr($length=16) { $chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $str=""; for ($i=0; $i<$length; $i++) { $str .=substr($chars, mt_rand(0, strlen($chars) -1), 1); } return$str; } privatefunctiongetJsApiTicket() { // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例$data=json_decode($this->get_php_file("jsapi_ticket.php")); if ($data->expire_time<time()) { $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; } return$ticket; } privatefunctiongetAccessToken() { // access_token 应该全局存储与更新,以下代码以写入到文件中做示例$data=json_decode($this->get_php_file("access_token.php")); if ($data->expire_time<time()) { // 如果是企业号用以下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)); $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; } return$access_token; } privatefunctionhttpGet($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; } privatefunctionget_php_file($filename) { returntrim(substr(file_get_contents($filename), 15)); } privatefunctionset_php_file($filename, $content) { $fp=fopen($filename, "w"); fwrite($fp, "<?php exit();?>" . $content); fclose($fp); } }
🎈 JS-SDK 签名注意事项
- 由微信官方可知,
jsapiTicket
和access_token
调用一次可以在2
小时内使用,也就是7200
秒,所以我们在拿到这个值的时候,需要将其缓存
,官方文档中缓存了7000
秒,为了防止不必要的问题产生,所以官方提前了200
秒 - 关于为什么要缓存这两个值,主要是因为
同一个公众号
每天调用这个值的上限是2000
次,如果不缓存,如果当天你的服务访问次数超过2000
次,因为没有缓存,就会达到限制,服务无法正常使用了 - 官方使用的缓存是放在
jsapi_ticket.php
和access_token.php
两个文件中的,当然你可以放到redis
和mongodb
中,但是不推荐存储在数据库中,容易造成大量的I/O
开销
require_once"jssdk.php"; $jssdk=newJSSDK("yourAppID", "yourAppSecret"); $signPackage=$jssdk->GetSignPackage(); <htmllang="en"><head><metacharset="UTF-8"><title></title></head><body></body><scriptsrc="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: 'echo$signPackage["appId"];', timestamp: echo$signPackage["timestamp"]; , nonceStr: 'echo$signPackage["nonceStr"];', signature: 'echo$signPackage["signature"];', jsApiList: [ // 所有要调用的 API 都要加到这个列表中 ] }); wx.ready(function () { // 在这里调用 API }); </script></html>
🎈 自定义微信分享
- 想要调用
JS-SDK
中的接口,必须先在wx.config
中jsApiList
中添加你需要使用的API
,不然无法使用 - 经常项目中做的
H5
,为了更好的分享,在微信中需要自定义分享的icon
、分享的标题
、分享的简介
和跳转链接
- 因为一般分享信息在项目加载的时候就要初始化,所以需要放到
ready
中进行初始化 - 当然,如果你的分享信息是变化的,则可以通过点击事件在调用分享接口也是可以的
wx.config({ debug: true, appId: '<?php echo $signPackage["appId"];?>', timestamp: <?phpecho$signPackage["timestamp"];?>, nonceStr: '<?php echo $signPackage["nonceStr"];?>', signature: '<?php echo $signPackage["signature"];?>', jsApiList: [ 'checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', ] }); wx.ready(function () { // 获取“分享到朋友圈”按钮点击状态及自定义分享内容接口wx.onMenuShareTimeline({ title: '', // 分享标题link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号 JS 安全域名一致imgUrl: '', // 分享图标success: function () { // 用户点击了分享后执行的回调函数 } }), // 获取“分享给朋友”按钮点击状态及自定义分享内容接口wx.onMenuShareAppMessage({ title: '', // 分享标题desc: '', // 分享描述link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号 JS 安全域名一致imgUrl: '', // 分享图标type: '', // 分享类型,music、video或link,不填默认为linkdataUrl: '', // 如果 type 是music或video,则要提供数据链接,默认为空success: function () { // 用户点击了分享后执行的回调函数 } }); wx.onMenuShareWeibo({ title: '', // 分享标题desc: '', // 分享描述link: '', // 分享链接imgUrl: '', // 分享图标success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 } }); });
🎈 拍照选图功能
- 有时候需要通过
JS-SDK
调用手机摄像头进行拍照,然后处理图片 - 需要注意的是上传图片接口,上传图片有效期
3
天,可用微信多媒体接口下载图片到自己的服务器
wx.config({ debug: true, appId: '<?php echo $signPackage["appId"];?>', timestamp: <?phpecho$signPackage["timestamp"];?>, nonceStr: '<?php echo $signPackage["nonceStr"];?>', signature: '<?php echo $signPackage["signature"];?>', jsApiList: [ 'checkJsApi', 'chooseImage', 'previewImage', 'downloadImage', 'getLocalImgData', ] }); // 拍照或从手机相册中选图接口wx.chooseImage({ count: 1, // 默认9sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有success: function (res) { varlocalIds=res.localIds; // 返回选定照片的本地 ID 列表,localId可以作为 img 标签的 src 属性显示图片 } }); // 预览图片接口wx.previewImage({ current: '', // 当前显示图片的 http 链接urls: [] // 需要预览的图片 http 链接列表}); // 上传图片接口wx.uploadImage({ localId: '', // 需要上传的图片的本地ID,由 chooseImage 接口获得isShowProgressTips: 1, // 默认为1,显示进度提示success: function (res) { varserverId=res.serverId; // 返回图片的服务器端ID } }); // 下载图片接口wx.downloadImage({ serverId: '', // 需要下载的图片的服务器端ID,由 uploadImage 接口获得isShowProgressTips: 1, // 默认为1,显示进度提示success: function (res) { varlocalId=res.localId; // 返回图片下载后的本地ID } });
🎈 录制音频处理
- 可以使用
JS-SDK
实现录音
、上传录音
、播放语音
等功能,可以在你的项目中大大增加用户的参与感 - 比如可以通过录一段用户的语音,然后通过语音识别机器人自动回复,再通过
播放语音功能
将回复的内容播放出来,就简单形成了一个你问我答的小游戏
wx.config({ debug: true, appId: '<?php echo $signPackage["appId"];?>', timestamp: <?phpecho$signPackage["timestamp"];?>, nonceStr: '<?php echo $signPackage["nonceStr"];?>', signature: '<?php echo $signPackage["signature"];?>', jsApiList: [ 'checkJsApi', 'startRecord', 'stopRecord', 'onVoiceRecordEnd', 'playVoice', 'pauseVoice', 'stopVoice', 'onVoicePlayEnd', 'uploadVoice', 'downloadVoice' ] }); // 开始录音接口,可以放在点击事件中触发wx.startRecord(); // 停止录音接口wx.stopRecord({ success: function (res) { varlocalId=res.localId; } }); // 监听录音自动停止接口wx.onVoiceRecordEnd({ // 录音时间超过一分钟没有停止的时候会执行 complete 回调complete: function (res) { varlocalId=res.localId; } }); // 播放语音接口wx.playVoice({ localId: ''// 需要播放的音频的本地ID,由 stopRecord 接口获得}); // 暂停播放接口wx.pauseVoice({ localId: ''// 需要暂停的音频的本地ID,由 stopRecord 接口获得}); // 上传语音接口wx.uploadVoice({ localId: '', // 需要上传的音频的本地ID,由 stopRecord 接口获得isShowProgressTips: 1, // 默认为1,显示进度提示success: function (res) { varserverId=res.serverId; // 返回音频的服务器端ID } });
🎈 获取地理位置
- 可以通过
JS-SDK
获取当前用户所处位置的经纬度,这样就可以给用户推荐一些周边的消费啥的 - 也可以通过位置信息,给用户
推荐
一些周边的个性化娱乐等服务是非常的方便的
// 使用微信内置地图查看位置接口wx.openLocation({ latitude: 0, // 纬度,浮点数,范围为90 ~ -90longitude: 0, // 经度,浮点数,范围为180 ~ -180。name: '', // 位置名address: '', // 地址详情说明scale: 1, // 地图缩放级别,整型值,范围从1~28。默认为最大infoUrl: ''// 在查看位置界面底部显示的超链接,可点击跳转}); // 获取地理位置接口wx.getLocation({ type: 'wgs84', // 默认为wgs84的 gps 坐标,如果要返回直接给 openLocation 用的火星坐标,可传入'gcj02'success: function (res) { varlatitude=res.latitude; // 纬度,浮点数,范围为90 ~ -90varlongitude=res.longitude; // 经度,浮点数,范围为180 ~ -180。varspeed=res.speed; // 速度,以米/每秒计varaccuracy=res.accuracy; // 位置精度 } });
🎈 微信摇一摇
- 如果你想通过微信摇一摇自己开发一些功能,可以使用
JS-SDK
中的摇一摇功能
// 开启查找周边 ibeacon 设备接口wx.startSearchBeacons({ ticket:"", //摇周边的业务 ticket , 系统自动添加在摇出来的页面链接后面complete:function(argv){ //开启查找完成后的回调函数 } }); // 关闭查找周边 ibeacon 设备接口wx.stopSearchBeacons({ complete:function(res){ //关闭查找完成后的回调函数 } }); // 监听周边 ibeacon 设备接口wx.onSearchBeacons({ complete:function(argv){ //回调函数,可以数组形式取得该商家注册的在周边的相关设备列表 } });
🎈 微信扫一扫
- 如果你想调用微信扫一扫的功能,可以使用
scanQRCode
接口 - 在
success
回调方法中,获得扫描结果,然后可以通过扫描结果自己去进行二次开发,是非常的方便的
// 调起微信扫一扫接口wx.scanQRCode({ needResult: 0, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有success: function (res) { varresult=res.resultStr; // 当needResult 为 1 时,扫码返回的结果 } });