曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 1723|回复: 1
打印 上一主题 下一主题

微信 JS-SDK 相关操作 PHP 版

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2017-3-31 10:18:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
代码为网上摘抄,基本为官方 Demo 。

1. JS-SDK 后台操作代码
  1. <?php
  2. class JSSDK {
  3.   private $appId;
  4.   private $appSecret;

  5.   public function __construct($appId, $appSecret) {
  6.     $this->appId = $appId;
  7.     $this->appSecret = $appSecret;
  8.   }

  9.   public function getSignPackage() {
  10.     $jsapiTicket = $this->getJsApiTicket();

  11.     // 注意 URL 一定要动态获取,不能 hardcode.
  12.     $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
  13.     $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

  14.     $timestamp = time();
  15.     $nonceStr = $this->createNonceStr();

  16.     // 这里参数的顺序要按照 key 值 ASCII 码升序排序
  17.     $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url";

  18.     $signature = sha1($string);

  19.     $signPackage = array(
  20.       "appId"     => $this->appId,
  21.       "nonceStr"  => $nonceStr,
  22.       "timestamp" => $timestamp,
  23.       "url"       => $url,
  24.       "signature" => $signature,
  25.       "rawString" => $string
  26.     );
  27.     return $signPackage;
  28.   }

  29.   private function createNonceStr($length = 16) {
  30.     $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  31.     $str = "";
  32.     for ($i = 0; $i < $length; $i++) {
  33.       $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
  34.     }
  35.     return $str;
  36.   }

  37.   private function getJsApiTicket() {
  38.     // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例
  39.     $data = json_decode(file_get_contents("jsapi_ticket.json"));
  40.     if ($data->expire_time < time()) {
  41.       $accessToken = $this->getAccessToken();
  42.       // 如果是企业号用以下 URL 获取 ticket
  43.       // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken";
  44.       $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
  45.       $res = json_decode($this->httpGet($url));
  46.       $ticket = $res->ticket;
  47.       if ($ticket) {
  48.         $data->expire_time = time() + 7000;
  49.         $data->jsapi_ticket = $ticket;
  50.         $fp = fopen("jsapi_ticket.json", "w");
  51.         fwrite($fp, json_encode($data));
  52.         fclose($fp);
  53.       }
  54.     } else {
  55.       $ticket = $data->jsapi_ticket;
  56.     }

  57.     return $ticket;
  58.   }

  59.   private function getAccessToken() {
  60.     // access_token 应该全局存储与更新,以下代码以写入到文件中做示例
  61.     $data = json_decode(file_get_contents("access_token.json"));
  62.     if ($data->expire_time < time()) {
  63.       // 如果是企业号用以下URL获取access_token
  64.       // $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret";
  65.       $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";
  66.       $res = json_decode($this->httpGet($url));
  67.       $access_token = $res->access_token;
  68.       if ($access_token) {
  69.         $data->expire_time = time() + 7000;
  70.         $data->access_token = $access_token;
  71.         $fp = fopen("access_token.json", "w");
  72.         fwrite($fp, json_encode($data));
  73.         fclose($fp);
  74.       }
  75.     } else {
  76.       $access_token = $data->access_token;
  77.     }
  78.     return $access_token;
  79.   }

  80.   private function httpGet($url) {
  81.     $curl = curl_init();
  82.     curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  83.     curl_setopt($curl, CURLOPT_TIMEOUT, 500);
  84.     curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  85.     curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
  86.     curl_setopt($curl, CURLOPT_URL, $url);

  87.     $res = curl_exec($curl);
  88.     curl_close($curl);

  89.     return $res;
  90.   }
  91. }
复制代码


sample.php这个是微信的前台展示页面,需要注意:其中的微信id和秘钥需要换成自己的微信公众账号的,代码 :
  1. <?php
  2. require_once "jssdk.php";
  3. $jssdk = new JSSDK("自己的微信id", "自己的秘钥");
  4. $signPackage = $jssdk->GetSignPackage();
  5. ?>
  6. <!DOCTYPE html>
  7. <html>
  8. <head>
  9.   <meta charset="utf-8">
  10.   <title>微信JS-SDK Demo</title>
  11.   <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
  12.   <link rel="stylesheet" href="style.css">
  13. </head>
  14. <body>
  15. <div class="wxapi_container">
  16.     <div class="wxapi_index_container">
  17.       <ul class="label_box lbox_close wxapi_index_list">
  18.         <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-basic">基础接口</a></li>
  19.         <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-share">分享接口</a></li>
  20.         <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-image">图像接口</a></li>
  21.         <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-voice">音频接口</a></li>
  22.         <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-smart">智能接口</a></li>
  23.         <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-device">设备信息接口</a></li>
  24.         <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-location">地理位置接口</a></li>
  25.         <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-webview">界面操作接口</a></li>
  26.         <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-scan">微信扫一扫接口</a></li>
  27.         <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-shopping">微信小店接口</a></li>
  28.         <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-card">微信卡券接口</a></li>
  29.         <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-pay">微信支付接口</a></li>
  30.       </ul>
  31.     </div>
  32.     <div class="lbox_close wxapi_form">
  33.       <h3 id="menu-basic">基础接口</h3>
  34.       <span class="desc">判断当前客户端是否支持指定JS接口</span>
  35.       <button class="btn btn_primary" id="checkJsApi">checkJsApi</button>

  36.       <h3 id="menu-share">分享接口</h3>
  37.       <span class="desc">获取“分享到朋友圈”按钮点击状态及自定义分享内容接口</span>
  38.       <button class="btn btn_primary" id="onMenuShareTimeline">onMenuShareTimeline</button>
  39.       <span class="desc">获取“分享给朋友”按钮点击状态及自定义分享内容接口</span>
  40.       <button class="btn btn_primary" id="onMenuShareAppMessage">onMenuShareAppMessage</button>
  41.       <span class="desc">获取“分享到QQ”按钮点击状态及自定义分享内容接口</span>
  42.       <button class="btn btn_primary" id="onMenuShareQQ">onMenuShareQQ</button>
  43.       <span class="desc">获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口</span>
  44.       <button class="btn btn_primary" id="onMenuShareWeibo">onMenuShareWeibo</button>

  45.       <h3 id="menu-image">图像接口</h3>
  46.       <span class="desc">拍照或从手机相册中选图接口</span>
  47.       <button class="btn btn_primary" id="chooseImage">chooseImage</button>
  48.       <span class="desc">预览图片接口</span>
  49.       <button class="btn btn_primary" id="previewImage">previewImage</button>
  50.       <span class="desc">上传图片接口</span>
  51.       <button class="btn btn_primary" id="uploadImage">uploadImage</button>
  52.       <span class="desc">下载图片接口</span>
  53.       <button class="btn btn_primary" id="downloadImage">downloadImage</button>

  54.       <h3 id="menu-voice">音频接口</h3>
  55.       <span class="desc">开始录音接口</span>
  56.       <button class="btn btn_primary" id="startRecord">startRecord</button>
  57.       <span class="desc">停止录音接口</span>
  58.       <button class="btn btn_primary" id="stopRecord">stopRecord</button>
  59.       <span class="desc">播放语音接口</span>
  60.       <button class="btn btn_primary" id="playVoice">playVoice</button>
  61.       <span class="desc">暂停播放接口</span>
  62.       <button class="btn btn_primary" id="pauseVoice">pauseVoice</button>
  63.       <span class="desc">停止播放接口</span>
  64.       <button class="btn btn_primary" id="stopVoice">stopVoice</button>
  65.       <span class="desc">上传语音接口</span>
  66.       <button class="btn btn_primary" id="uploadVoice">uploadVoice</button>
  67.       <span class="desc">下载语音接口</span>
  68.       <button class="btn btn_primary" id="downloadVoice">downloadVoice</button>

  69.       <h3 id="menu-smart">智能接口</h3>
  70.       <span class="desc">识别音频并返回识别结果接口</span>
  71.       <button class="btn btn_primary" id="translateVoice">translateVoice</button>

  72.       <h3 id="menu-device">设备信息接口</h3>
  73.       <span class="desc">获取网络状态接口</span>
  74.       <button class="btn btn_primary" id="getNetworkType">getNetworkType</button>

  75.       <h3 id="menu-location">地理位置接口</h3>
  76.       <span class="desc">使用微信内置地图查看位置接口</span>
  77.       <button class="btn btn_primary" id="openLocation">openLocation</button>
  78.       <span class="desc">获取地理位置接口</span>
  79.       <button class="btn btn_primary" id="getLocation">getLocation</button>

  80.       <h3 id="menu-webview">界面操作接口</h3>
  81.       <span class="desc">隐藏右上角菜单接口</span>
  82.       <button class="btn btn_primary" id="hideOptionMenu">hideOptionMenu</button>
  83.       <span class="desc">显示右上角菜单接口</span>
  84.       <button class="btn btn_primary" id="showOptionMenu">showOptionMenu</button>
  85.       <span class="desc">关闭当前网页窗口接口</span>
  86.       <button class="btn btn_primary" id="closeWindow">closeWindow</button>
  87.       <span class="desc">批量隐藏功能按钮接口</span>
  88.       <button class="btn btn_primary" id="hideMenuItems">hideMenuItems</button>
  89.       <span class="desc">批量显示功能按钮接口</span>
  90.       <button class="btn btn_primary" id="showMenuItems">showMenuItems</button>
  91.       <span class="desc">隐藏所有非基础按钮接口</span>
  92.       <button class="btn btn_primary" id="hideAllNonBaseMenuItem">hideAllNonBaseMenuItem</button>
  93.       <span class="desc">显示所有功能按钮接口</span>
  94.       <button class="btn btn_primary" id="showAllNonBaseMenuItem">showAllNonBaseMenuItem</button>

  95.       <h3 id="menu-scan">微信扫一扫</h3>
  96.       <span class="desc">调起微信扫一扫接口</span>
  97.       <button class="btn btn_primary" id="scanQRCode0">scanQRCode(微信处理结果)</button>
  98.       <button class="btn btn_primary" id="scanQRCode1">scanQRCode(直接返回结果)</button>

  99.       <h3 id="menu-shopping">微信小店接口</h3>
  100.       <span class="desc">跳转微信商品页接口</span>
  101.       <button class="btn btn_primary" id="openProductSpecificView">openProductSpecificView</button>

  102.       <h3 id="menu-card">微信卡券接口</h3>
  103.       <span class="desc">批量添加卡券接口</span>
  104.       <button class="btn btn_primary" id="addCard">addCard</button>
  105.       <span class="desc">调起适用于门店的卡券列表并获取用户选择列表</span>
  106.       <button class="btn btn_primary" id="chooseCard">chooseCard</button>
  107.       <span class="desc">查看微信卡包中的卡券接口</span>
  108.       <button class="btn btn_primary" id="openCard">openCard</button>

  109.       <h3 id="menu-pay">微信支付接口</h3>
  110.       <span class="desc">发起一个微信支付请求</span>
  111.       <button class="btn btn_primary" id="chooseWXPay">chooseWXPay</button>
  112.     </div>
  113.   </div>
  114. </body>
  115. <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
  116. <script>
  117.   /*
  118.    * 注意:
  119.    * 1. 所有的JS接口只能在公众号绑定的域名下调用,公众号开发者需要先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
  120.    * 2. 如果发现在 Android 不能分享自定义内容,请到官网下载最新的包覆盖安装,Android 自定义分享接口需升级至 6.0.2.58 版本及以上。
  121.    * 3. 常见问题及完整 JS-SDK 文档地址:[url]http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html[/url]
  122.    *
  123.    * 开发中遇到问题详见文档“附录5-常见错误及解决办法”解决,如仍未能解决可通过以下渠道反馈:
  124.    * 邮箱地址:[email]weixin-open@qq.com[/email]
  125.    * 邮件主题:【微信JS-SDK反馈】具体问题
  126.    * 邮件内容说明:用简明的语言描述问题所在,并交代清楚遇到该问题的场景,可附上截屏图片,微信团队会尽快处理你的反馈。
  127.    */
  128.   wx.config({
  129.       debug: true,
  130.       appId: '<?php echo $signPackage["appId"];?>',
  131.       timestamp: <?php echo $signPackage["timestamp"];?>,
  132.       nonceStr: '<?php echo $signPackage["nonceStr"];?>',
  133.       signature: '<?php echo $signPackage["signature"];?>',
  134.       jsApiList: [
  135.         'checkJsApi',
  136.         'onMenuShareTimeline',
  137.         'onMenuShareAppMessage',
  138.         'onMenuShareQQ',
  139.         'onMenuShareWeibo',
  140.         'hideMenuItems',
  141.         'showMenuItems',
  142.         'hideAllNonBaseMenuItem',
  143.         'showAllNonBaseMenuItem',
  144.         'translateVoice',
  145.         'startRecord',
  146.         'stopRecord',
  147.         'onRecordEnd',
  148.         'playVoice',
  149.         'pauseVoice',
  150.         'stopVoice',
  151.         'uploadVoice',
  152.         'downloadVoice',
  153.         'chooseImage',
  154.         'previewImage',
  155.         'uploadImage',
  156.         'downloadImage',
  157.         'getNetworkType',
  158.         'openLocation',
  159.         'getLocation',
  160.         'hideOptionMenu',
  161.         'showOptionMenu',
  162.         'closeWindow',
  163.         'scanQRCode',
  164.         'chooseWXPay',
  165.         'openProductSpecificView',
  166.         'addCard',
  167.         'chooseCard',
  168.         'openCard'
  169.       ]
  170.   });
  171. </script>
  172. <script src="demo.js"> </script>
  173. </html>
复制代码



demo.js这个是微信的js事件,代码:
  1. /*
  2. * 注意:
  3. * 1. 所有的JS接口只能在公众号绑定的域名下调用,公众号开发者需要先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
  4. * 2. 如果发现在 Android 不能分享自定义内容,请到官网下载最新的包覆盖安装,Android 自定义分享接口需升级至 6.0.2.58 版本及以上。
  5. * 3. 完整 JS-SDK 文档地址:[url]http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html[/url]
  6. *
  7. * 如有问题请通过以下渠道反馈:
  8. * 邮箱地址:[email]weixin-open@qq.com[/email]
  9. * 邮件主题:【微信JS-SDK反馈】具体问题
  10. * 邮件内容说明:用简明的语言描述问题所在,并交代清楚遇到该问题的场景,可附上截屏图片,微信团队会尽快处理你的反馈。
  11. */
  12. wx.ready(function () {
  13.   // 1 判断当前版本是否支持指定 JS 接口,支持批量判断
  14.   document.querySelector('#checkJsApi').onclick = function () {
  15.     wx.checkJsApi({
  16.       jsApiList: [
  17.         'getNetworkType',
  18.         'previewImage'
  19.       ],
  20.       success: function (res) {
  21.         alert(JSON.stringify(res));
  22.       }
  23.     });
  24.   };

  25.   // 2. 分享接口
  26.   // 2.1 监听“分享给朋友”,按钮点击、自定义分享内容及分享结果接口
  27.   document.querySelector('#onMenuShareAppMessage').onclick = function () {
  28.     wx.onMenuShareAppMessage({
  29.       title: '互联网之子',
  30.       desc: '在长大的过程中,我才慢慢发现,我身边的所有事,别人跟我说的所有事,那些所谓本来如此,注定如此的事,它们其实没有非得如此,事情是可以改变的。更重要的是,有些事既然错了,那就该做出改变。',
  31.       link: 'http://movie.douban.com/subject/25785114/',
  32.       imgUrl: 'http://demo.open.weixin.qq.com/jssdk/images/p2166127561.jpg',
  33.       trigger: function (res) {
  34.         // 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回
  35.         alert('用户点击发送给朋友');
  36.       },
  37.       success: function (res) {
  38.         alert('已分享');
  39.       },
  40.       cancel: function (res) {
  41.         alert('已取消');
  42.       },
  43.       fail: function (res) {
  44.         alert(JSON.stringify(res));
  45.       }
  46.     });
  47.     alert('已注册获取“发送给朋友”状态事件');
  48.   };

  49.   // 2.2 监听“分享到朋友圈”按钮点击、自定义分享内容及分享结果接口
  50.   document.querySelector('#onMenuShareTimeline').onclick = function () {
  51.     wx.onMenuShareTimeline({
  52.       title: '互联网之子',
  53.       link: 'http://movie.douban.com/subject/25785114/',
  54.       imgUrl: 'http://demo.open.weixin.qq.com/jssdk/images/p2166127561.jpg',
  55.       trigger: function (res) {
  56.         // 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回
  57.         alert('用户点击分享到朋友圈');
  58.       },
  59.       success: function (res) {
  60.         alert('已分享');
  61.       },
  62.       cancel: function (res) {
  63.         alert('已取消');
  64.       },
  65.       fail: function (res) {
  66.         alert(JSON.stringify(res));
  67.       }
  68.     });
  69.     alert('已注册获取“分享到朋友圈”状态事件');
  70.   };

  71.   // 2.3 监听“分享到QQ”按钮点击、自定义分享内容及分享结果接口
  72.   document.querySelector('#onMenuShareQQ').onclick = function () {
  73.     wx.onMenuShareQQ({
  74.       title: '互联网之子',
  75.       desc: '在长大的过程中,我才慢慢发现,我身边的所有事,别人跟我说的所有事,那些所谓本来如此,注定如此的事,它们其实没有非得如此,事情是可以改变的。更重要的是,有些事既然错了,那就该做出改变。',
  76.       link: 'http://movie.douban.com/subject/25785114/',
  77.       imgUrl: 'http://img3.douban.com/view/movie_poster_cover/spst/public/p2166127561.jpg',
  78.       trigger: function (res) {
  79.         alert('用户点击分享到QQ');
  80.       },
  81.       complete: function (res) {
  82.         alert(JSON.stringify(res));
  83.       },
  84.       success: function (res) {
  85.         alert('已分享');
  86.       },
  87.       cancel: function (res) {
  88.         alert('已取消');
  89.       },
  90.       fail: function (res) {
  91.         alert(JSON.stringify(res));
  92.       }
  93.     });
  94.     alert('已注册获取“分享到 QQ”状态事件');
  95.   };
  96.   
  97.   // 2.4 监听“分享到微博”按钮点击、自定义分享内容及分享结果接口
  98.   document.querySelector('#onMenuShareWeibo').onclick = function () {
  99.     wx.onMenuShareWeibo({
  100.       title: '互联网之子',
  101.       desc: '在长大的过程中,我才慢慢发现,我身边的所有事,别人跟我说的所有事,那些所谓本来如此,注定如此的事,它们其实没有非得如此,事情是可以改变的。更重要的是,有些事既然错了,那就该做出改变。',
  102.       link: 'http://movie.douban.com/subject/25785114/',
  103.       imgUrl: 'http://img3.douban.com/view/movie_poster_cover/spst/public/p2166127561.jpg',
  104.       trigger: function (res) {
  105.         alert('用户点击分享到微博');
  106.       },
  107.       complete: function (res) {
  108.         alert(JSON.stringify(res));
  109.       },
  110.       success: function (res) {
  111.         alert('已分享');
  112.       },
  113.       cancel: function (res) {
  114.         alert('已取消');
  115.       },
  116.       fail: function (res) {
  117.         alert(JSON.stringify(res));
  118.       }
  119.     });
  120.     alert('已注册获取“分享到微博”状态事件');
  121.   };


  122.   // 3 智能接口
  123.   var voice = {
  124.     localId: '',
  125.     serverId: ''
  126.   };
  127.   // 3.1 识别音频并返回识别结果
  128.   document.querySelector('#translateVoice').onclick = function () {
  129.     if (voice.localId == '') {
  130.       alert('请先使用 startRecord 接口录制一段声音');
  131.       return;
  132.     }
  133.     wx.translateVoice({
  134.       localId: voice.localId,
  135.       complete: function (res) {
  136.         if (res.hasOwnProperty('translateResult')) {
  137.           alert('识别结果:' + res.translateResult);
  138.         } else {
  139.           alert('无法识别');
  140.         }
  141.       }
  142.     });
  143.   };

  144.   // 4 音频接口
  145.   // 4.2 开始录音
  146.   document.querySelector('#startRecord').onclick = function () {
  147.     wx.startRecord({
  148.       cancel: function () {
  149.         alert('用户拒绝授权录音');
  150.       }
  151.     });
  152.   };

  153.   // 4.3 停止录音
  154.   document.querySelector('#stopRecord').onclick = function () {
  155.     wx.stopRecord({
  156.       success: function (res) {
  157.         voice.localId = res.localId;
  158.       },
  159.       fail: function (res) {
  160.         alert(JSON.stringify(res));
  161.       }
  162.     });
  163.   };

  164.   // 4.4 监听录音自动停止
  165.   wx.onVoiceRecordEnd({
  166.     complete: function (res) {
  167.       voice.localId = res.localId;
  168.       alert('录音时间已超过一分钟');
  169.     }
  170.   });

  171.   // 4.5 播放音频
  172.   document.querySelector('#playVoice').onclick = function () {
  173.     if (voice.localId == '') {
  174.       alert('请先使用 startRecord 接口录制一段声音');
  175.       return;
  176.     }
  177.     wx.playVoice({
  178.       localId: voice.localId
  179.     });
  180.   };

  181.   // 4.6 暂停播放音频
  182.   document.querySelector('#pauseVoice').onclick = function () {
  183.     wx.pauseVoice({
  184.       localId: voice.localId
  185.     });
  186.   };

  187.   // 4.7 停止播放音频
  188.   document.querySelector('#stopVoice').onclick = function () {
  189.     wx.stopVoice({
  190.       localId: voice.localId
  191.     });
  192.   };

  193.   // 4.8 监听录音播放停止
  194.   wx.onVoicePlayEnd({
  195.     complete: function (res) {
  196.       alert('录音(' + res.localId + ')播放结束');
  197.     }
  198.   });

  199.   // 4.8 上传语音
  200.   document.querySelector('#uploadVoice').onclick = function () {
  201.     if (voice.localId == '') {
  202.       alert('请先使用 startRecord 接口录制一段声音');
  203.       return;
  204.     }
  205.     wx.uploadVoice({
  206.       localId: voice.localId,
  207.       success: function (res) {
  208.         alert('上传语音成功,serverId 为' + res.serverId);
  209.         voice.serverId = res.serverId;
  210.       }
  211.     });
  212.   };

  213.   // 4.9 下载语音
  214.   document.querySelector('#downloadVoice').onclick = function () {
  215.     if (voice.serverId == '') {
  216.       alert('请先使用 uploadVoice 上传声音');
  217.       return;
  218.     }
  219.     wx.downloadVoice({
  220.       serverId: voice.serverId,
  221.       success: function (res) {
  222.         alert('下载语音成功,localId 为' + res.localId);
  223.         voice.localId = res.localId;
  224.       }
  225.     });
  226.   };

  227.   // 5 图片接口
  228.   // 5.1 拍照、本地选图
  229.   var images = {
  230.     localId: [],
  231.     serverId: []
  232.   };
  233.   document.querySelector('#chooseImage').onclick = function () {
  234.     wx.chooseImage({
  235.       success: function (res) {
  236.         images.localId = res.localIds;
  237.         alert('已选择 ' + res.localIds.length + ' 张图片');
  238.       }
  239.     });
  240.   };

  241.   // 5.2 图片预览
  242.   document.querySelector('#previewImage').onclick = function () {
  243.     wx.previewImage({
  244.       current: 'http://img5.douban.com/view/photo/photo/public/p1353993776.jpg',
  245.       urls: [
  246.         'http://img3.douban.com/view/photo/photo/public/p2152117150.jpg',
  247.         'http://img5.douban.com/view/photo/photo/public/p1353993776.jpg',
  248.         'http://img3.douban.com/view/photo/photo/public/p2152134700.jpg'
  249.       ]
  250.     });
  251.   };

  252.   // 5.3 上传图片
  253.   document.querySelector('#uploadImage').onclick = function () {
  254.     if (images.localId.length == 0) {
  255.       alert('请先使用 chooseImage 接口选择图片');
  256.       return;
  257.     }
  258.     var i = 0, length = images.localId.length;
  259.     images.serverId = [];
  260.     function upload() {
  261.       wx.uploadImage({
  262.         localId: images.localId[i],
  263.         success: function (res) {
  264.           i++;
  265.           alert('已上传:' + i + '/' + length);
  266.           images.serverId.push(res.serverId);
  267.           if (i < length) {
  268.             upload();
  269.           }
  270.         },
  271.         fail: function (res) {
  272.           alert(JSON.stringify(res));
  273.         }
  274.       });
  275.     }
  276.     upload();
  277.   };

  278.   // 5.4 下载图片
  279.   document.querySelector('#downloadImage').onclick = function () {
  280.     if (images.serverId.length === 0) {
  281.       alert('请先使用 uploadImage 上传图片');
  282.       return;
  283.     }
  284.     var i = 0, length = images.serverId.length;
  285.     images.localId = [];
  286.     function download() {
  287.       wx.downloadImage({
  288.         serverId: images.serverId[i],
  289.         success: function (res) {
  290.           i++;
  291.           alert('已下载:' + i + '/' + length);
  292.           images.localId.push(res.localId);
  293.           if (i < length) {
  294.             download();
  295.           }
  296.         }
  297.       });
  298.     }
  299.     download();
  300.   };

  301.   // 6 设备信息接口
  302.   // 6.1 获取当前网络状态
  303.   document.querySelector('#getNetworkType').onclick = function () {
  304.     wx.getNetworkType({
  305.       success: function (res) {
  306.         alert(res.networkType);
  307.       },
  308.       fail: function (res) {
  309.         alert(JSON.stringify(res));
  310.       }
  311.     });
  312.   };

  313.   // 7 地理位置接口
  314.   // 7.1 查看地理位置
  315.   document.querySelector('#openLocation').onclick = function () {
  316.     wx.openLocation({
  317.       latitude: 23.099994,
  318.       longitude: 113.324520,
  319.       name: 'TIT 创意园',
  320.       address: '广州市海珠区新港中路 397 号',
  321.       scale: 14,
  322.       infoUrl: 'http://weixin.qq.com'
  323.     });
  324.   };

  325.   // 7.2 获取当前地理位置
  326.   document.querySelector('#getLocation').onclick = function () {
  327.     wx.getLocation({
  328.       success: function (res) {
  329.         alert(JSON.stringify(res));
  330.       },
  331.       cancel: function (res) {
  332.         alert('用户拒绝授权获取地理位置');
  333.       }
  334.     });
  335.   };

  336.   // 8 界面操作接口
  337.   // 8.1 隐藏右上角菜单
  338.   document.querySelector('#hideOptionMenu').onclick = function () {
  339.     wx.hideOptionMenu();
  340.   };

  341.   // 8.2 显示右上角菜单
  342.   document.querySelector('#showOptionMenu').onclick = function () {
  343.     wx.showOptionMenu();
  344.   };

  345.   // 8.3 批量隐藏菜单项
  346.   document.querySelector('#hideMenuItems').onclick = function () {
  347.     wx.hideMenuItems({
  348.       menuList: [
  349.         'menuItem:readMode', // 阅读模式
  350.         'menuItem:share:timeline', // 分享到朋友圈
  351.         'menuItem:copyUrl' // 复制链接
  352.       ],
  353.       success: function (res) {
  354.         alert('已隐藏“阅读模式”,“分享到朋友圈”,“复制链接”等按钮');
  355.       },
  356.       fail: function (res) {
  357.         alert(JSON.stringify(res));
  358.       }
  359.     });
  360.   };

  361.   // 8.4 批量显示菜单项
  362.   document.querySelector('#showMenuItems').onclick = function () {
  363.     wx.showMenuItems({
  364.       menuList: [
  365.         'menuItem:readMode', // 阅读模式
  366.         'menuItem:share:timeline', // 分享到朋友圈
  367.         'menuItem:copyUrl' // 复制链接
  368.       ],
  369.       success: function (res) {
  370.         alert('已显示“阅读模式”,“分享到朋友圈”,“复制链接”等按钮');
  371.       },
  372.       fail: function (res) {
  373.         alert(JSON.stringify(res));
  374.       }
  375.     });
  376.   };

  377.   // 8.5 隐藏所有非基本菜单项
  378.   document.querySelector('#hideAllNonBaseMenuItem').onclick = function () {
  379.     wx.hideAllNonBaseMenuItem({
  380.       success: function () {
  381.         alert('已隐藏所有非基本菜单项');
  382.       }
  383.     });
  384.   };

  385.   // 8.6 显示所有被隐藏的非基本菜单项
  386.   document.querySelector('#showAllNonBaseMenuItem').onclick = function () {
  387.     wx.showAllNonBaseMenuItem({
  388.       success: function () {
  389.         alert('已显示所有非基本菜单项');
  390.       }
  391.     });
  392.   };

  393.   // 8.7 关闭当前窗口
  394.   document.querySelector('#closeWindow').onclick = function () {
  395.     wx.closeWindow();
  396.   };

  397.   // 9 微信原生接口
  398.   // 9.1.1 扫描二维码并返回结果
  399.   document.querySelector('#scanQRCode0').onclick = function () {
  400.     wx.scanQRCode();
  401.   };
  402.   // 9.1.2 扫描二维码并返回结果
  403.   document.querySelector('#scanQRCode1').onclick = function () {
  404.     wx.scanQRCode({
  405.       needResult: 1,
  406.       desc: 'scanQRCode desc',
  407.       success: function (res) {
  408.         alert(JSON.stringify(res));
  409.       }
  410.     });
  411.   };

  412.   // 10 微信支付接口
  413.   // 10.1 发起一个支付请求
  414.   document.querySelector('#chooseWXPay').onclick = function () {
  415.     // 注意:此 Demo 使用 2.7 版本支付接口实现,建议使用此接口时参考微信支付相关最新文档。
  416.     wx.chooseWXPay({
  417.       timestamp: 1414723227,
  418.       nonceStr: 'noncestr',
  419.       package: 'addition=action_id%3dgaby1234%26limit_pay%3d&bank_type=WX&body=innertest&fee_type=1&input_charset=GBK¬ify_url=http%3A%2F%2F120.204.206.246%2Fcgi-bin%2Fmmsupport-bin%2Fnotifypay&out_trade_no=1414723227818375338&partner=1900000109&spbill_create_ip=127.0.0.1&total_fee=1&sign=432B647FE95C7BF73BCD177CEECBEF8D',
  420.       signType: 'SHA1', // 注意:新版支付接口使用 MD5 加密
  421.       paySign: 'bd5b1933cda6e9548862944836a9b52e8c9a2b69'
  422.     });
  423.   };

  424.   // 11.3  跳转微信商品页
  425.   document.querySelector('#openProductSpecificView').onclick = function () {
  426.     wx.openProductSpecificView({
  427.       productId: 'pDF3iY_m2M7EQ5EKKKWd95kAxfNw'
  428.     });
  429.   };

  430.   // 12 微信卡券接口
  431.   // 12.1 添加卡券
  432.   document.querySelector('#addCard').onclick = function () {
  433.     wx.addCard({
  434.       cardList: [
  435.         {
  436.           cardId: 'pDF3iY9tv9zCGCj4jTXFOo1DxHdo',
  437.           cardExt: '{"code": "", "openid": "", "timestamp": "1418301401", "signature":"64e6a7cc85c6e84b726f2d1cbef1b36e9b0f9750"}'
  438.         },
  439.         {
  440.           cardId: 'pDF3iY9tv9zCGCj4jTXFOo1DxHdo',
  441.           cardExt: '{"code": "", "openid": "", "timestamp": "1418301401", "signature":"64e6a7cc85c6e84b726f2d1cbef1b36e9b0f9750"}'
  442.         }
  443.       ],
  444.       success: function (res) {
  445.         alert('已添加卡券:' + JSON.stringify(res.cardList));
  446.       }
  447.     });
  448.   };

  449.   // 12.2 选择卡券
  450.   document.querySelector('#chooseCard').onclick = function () {
  451.     wx.chooseCard({
  452.       cardSign: '97e9c5e58aab3bdf6fd6150e599d7e5806e5cb91',
  453.       timestamp: 1417504553,
  454.       nonceStr: 'k0hGdSXKZEj3Min5',
  455.       success: function (res) {
  456.         alert('已选择卡券:' + JSON.stringify(res.cardList));
  457.       }
  458.     });
  459.   };

  460.   // 12.3 查看卡券
  461.   document.querySelector('#openCard').onclick = function () {
  462.     alert('您没有该公众号的卡券无法打开卡券。');
  463.     wx.openCard({
  464.       cardList: [
  465.       ]
  466.     });
  467.   };

  468.   var shareData = {
  469.     title: '微信JS-SDK Demo',
  470.     desc: '微信JS-SDK,帮助第三方为用户提供更优质的移动web服务',
  471.     link: 'http://demo.open.weixin.qq.com/jssdk/',
  472.     imgUrl: 'http://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRt8Qia4lv7k3M9J1SKqKCImxJCt7j9rHYicKDI45jRPBxdzdyREWnk0ia0N5TMnMfth7SdxtzMvVgXg/0'
  473.   };
  474.   wx.onMenuShareAppMessage(shareData);
  475.   wx.onMenuShareTimeline(shareData);
  476. });

  477. wx.error(function (res) {
  478.   alert(res.errMsg);
  479. });
复制代码



style.css这个是微信的页面样式,主要是为了美观,代码:
  1. html {
  2.   -ms-text-size-adjust: 100%;
  3.   -webkit-text-size-adjust: 100%;
  4.   -webkit-user-select: none;
  5.   user-select: none;
  6. }
  7. body {
  8.   line-height: 1.6;
  9.   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  10.   background-color: #f1f0f6;
  11. }
  12. * {
  13.   margin: 0;
  14.   padding: 0;
  15. }
  16. button {
  17.   font-family: inherit;
  18.   font-size: 100%;
  19.   margin: 0;
  20.   *font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  21. }
  22. ul,
  23. ol {
  24.   padding-left: 0;
  25.   list-style-type: none;
  26. }
  27. a {
  28.   text-decoration: none;
  29. }
  30. .label_box {
  31.   background-color: #ffffff;
  32. }
  33. .label_item {
  34.   padding-left: 15px;
  35. }
  36. .label_inner {
  37.   padding-top: 10px;
  38.   padding-bottom: 10px;
  39.   min-height: 24px;
  40.   position: relative;
  41. }
  42. .label_inner:before {
  43.   content: " ";
  44.   position: absolute;
  45.   left: 0;
  46.   top: 0;
  47.   width: 200%;
  48.   height: 1px;
  49.   border-top: 1px solid #ededed;
  50.   -webkit-transform-origin: 0 0;
  51.   transform-origin: 0 0;
  52.   -webkit-transform: scale(0.5);
  53.   transform: scale(0.5);
  54.   top: auto;
  55.   bottom: -2px;
  56. }
  57. .lbox_close {
  58.   position: relative;
  59. }
  60. .lbox_close:before {
  61.   content: " ";
  62.   position: absolute;
  63.   left: 0;
  64.   top: 0;
  65.   width: 200%;
  66.   height: 1px;
  67.   border-top: 1px solid #ededed;
  68.   -webkit-transform-origin: 0 0;
  69.   transform-origin: 0 0;
  70.   -webkit-transform: scale(0.5);
  71.   transform: scale(0.5);
  72. }
  73. .lbox_close:after {
  74.   content: " ";
  75.   position: absolute;
  76.   left: 0;
  77.   top: 0;
  78.   width: 200%;
  79.   height: 1px;
  80.   border-top: 1px solid #ededed;
  81.   -webkit-transform-origin: 0 0;
  82.   transform-origin: 0 0;
  83.   -webkit-transform: scale(0.5);
  84.   transform: scale(0.5);
  85.   top: auto;
  86.   bottom: -2px;
  87. }
  88. .lbox_close .label_item:last-child .label_inner:before {
  89.   display: none;
  90. }
  91. .btn {
  92.   display: block;
  93.   margin-left: auto;
  94.   margin-right: auto;
  95.   padding-left: 14px;
  96.   padding-right: 14px;
  97.   font-size: 18px;
  98.   text-align: center;
  99.   text-decoration: none;
  100.   overflow: visible;
  101.   /*.btn_h(@btnHeight);*/
  102.   height: 42px;
  103.   border-radius: 5px;
  104.   -moz-border-radius: 5px;
  105.   -webkit-border-radius: 5px;
  106.   box-sizing: border-box;
  107.   -moz-box-sizing: border-box;
  108.   -webkit-box-sizing: border-box;
  109.   color: #ffffff;
  110.   line-height: 42px;
  111.   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
  112. }
  113. .btn.btn_inline {
  114.   display: inline-block;
  115. }
  116. .btn_primary {
  117.   background-color: #04be02;
  118. }
  119. .btn_primary:not(.btn_disabled):visited {
  120.   color: #ffffff;
  121. }
  122. .btn_primary:not(.btn_disabled):active {
  123.   color: rgba(255, 255, 255, 0.9);
  124.   background-color: #039702;
  125. }
  126. button.btn {
  127.   width: 100%;
  128.   border: 0;
  129.   outline: 0;
  130.   -webkit-appearance: none;
  131. }
  132. button.btn:focus {
  133.   outline: 0;
  134. }
  135. .wxapi_container {
  136.   font-size: 16px;
  137. }
  138. h1 {
  139.   font-size: 14px;
  140.   font-weight: 400;
  141.   line-height: 2em;
  142.   padding-left: 15px;
  143.   color: #8d8c92;
  144. }
  145. .desc {
  146.   font-size: 14px;
  147.   font-weight: 400;
  148.   line-height: 2em;
  149.   color: #8d8c92;
  150. }
  151. .wxapi_index_item a {
  152.   display: block;
  153.   color: #3e3e3e;
  154.   -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  155. }
  156. .wxapi_form {
  157.   background-color: #ffffff;
  158.   padding: 0 15px;
  159.   margin-top: 30px;
  160.   padding-bottom: 15px;
  161. }
  162. h3 {
  163.   padding-top: 16px;
  164.   margin-top: 25px;
  165.   font-size: 16px;
  166.   font-weight: 400;
  167.   color: #3e3e3e;
  168.   position: relative;
  169. }
  170. h3:first-child {
  171.   padding-top: 15px;
  172. }
  173. h3:before {
  174.   content: " ";
  175.   position: absolute;
  176.   left: 0;
  177.   top: 0;
  178.   width: 200%;
  179.   height: 1px;
  180.   border-top: 1px solid #ededed;
  181.   -webkit-transform-origin: 0 0;
  182.   transform-origin: 0 0;
  183.   -webkit-transform: scale(0.5);
  184.   transform: scale(0.5);
  185. }
  186. .btn {
  187.   margin-bottom: 15px;
  188. }
复制代码




注意:1.这个dome会生成两个文件access_token.json、jsapi_ticket.json,进行缓存,请确保有读写文件的权限。

2.确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。


4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
沙发
 楼主| 发表于 2017-4-1 21:17:29 | 只看该作者
示例用法:
  1. <!--weiixn share-->
  2.         <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
  3.         <script>
  4.            var weixin_json = '';
  5.            var thisUrl = encodeURIComponent(window.location.href);
  6.           $.getJSON('http://appdyn.www.gov.cn/weixin/sample.php?url='+thisUrl+'&jsoncallback=?', function(text) {
  7.                         if(text){
  8.                                 weixin_json = text;
  9.                                   wx.config({
  10.                                         debug: false,
  11.                                         appId: weixin_json.appId,
  12.                                         timestamp: weixin_json.timestamp,
  13.                                         nonceStr: weixin_json.nonceStr,
  14.                                         signature: weixin_json.signature,
  15.                                         jsApiList: [
  16.                                           // 所有要调用的 API 都要加到这个列表中
  17.                                                 'onMenuShareAppMessage','onMenuShareTimeline','onMenuShareQQ','onMenuShareWeibo'
  18.                                         ]
  19.                                   });

  20.                                   wx.ready(function () {
  21.                                         // 在这里调用 API
  22.                                          wx.onMenuShareAppMessage({
  23.                                                 title: '大礼包 | 你关心的,影响你的,国务院2016惠民政策全梳理', // 分享标题
  24.                                                 desc: '2016年这一年,改革持续发力,简政放权的“刀刃”落在“繁复”的行政审批事', // 分享描述
  25.                                                 imgUrl: 'http://app.[img]www.gov.cn/govdata/gov/201701/01/396159/thumbnail1_396159@2x.jpg[/img]?t=1483444530',
  26.                                                 type: '', // 分享类型,music、video或link,不填默认为link
  27.                                                 dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
  28.                                                 success: function () {
  29.                                                         // 用户确认分享后执行的回调函数
  30.                                                         //alert('OK');
  31.                                                 },
  32.                                                 cancel: function () {
  33.                                                         // 用户取消分享后执行的回调函数
  34.                                                         //alert('NONO');
  35.                                                 }
  36.                                         });
  37.                                         wx.onMenuShareTimeline({
  38.                                                 title: '大礼包 | 你关心的,影响你的,国务院2016惠民政策全梳理', // 分享标题
  39.                                                 desc: '2016年这一年,改革持续发力,简政放权的“刀刃”落在“繁复”的行政审批事', // 分享描述
  40.                                                 imgUrl: 'http://app.[img]www.gov.cn/govdata/gov/201701/01/396159/thumbnail1_396159@2x.jpg[/img]?t=1483444530',
  41.                                                 success: function () {
  42.                                                         // 用户确认分享后执行的回调函数
  43.                                                 },
  44.                                                 cancel: function () {
  45.                                                         // 用户取消分享后执行的回调函数
  46.                                                 }
  47.                                         });
  48.                                         wx.onMenuShareQQ({
  49.                                                 title: '大礼包 | 你关心的,影响你的,国务院2016惠民政策全梳理', // 分享标题
  50.                                                 desc: '2016年这一年,改革持续发力,简政放权的“刀刃”落在“繁复”的行政审批事', // 分享描述
  51.                                                 imgUrl: 'http://app.[img]www.gov.cn/govdata/gov/201701/01/396159/thumbnail1_396159@2x.jpg[/img]?t=1483444530',
  52.                                                 success: function () {
  53.                                                    // 用户确认分享后执行的回调函数
  54.                                                 },
  55.                                                 cancel: function () {
  56.                                                    // 用户取消分享后执行的回调函数
  57.                                                 }
  58.                                         });
  59.                                         wx.onMenuShareWeibo({
  60.                                                 title: '大礼包 | 你关心的,影响你的,国务院2016惠民政策全梳理', // 分享标题
  61.                                                 desc: '2016年这一年,改革持续发力,简政放权的“刀刃”落在“繁复”的行政审批事', // 分享描述
  62.                                                 imgUrl: 'http://app.[img]www.gov.cn/govdata/gov/201701/01/396159/thumbnail1_396159@2x.jpg[/img]?t=1483444530',
  63.                                                 success: function () {
  64.                                                    // 用户确认分享后执行的回调函数
  65.                                                 },
  66.                                                 cancel: function () {
  67.                                                         // 用户取消分享后执行的回调函数
  68.                                                 }
  69.                                         });
  70.                                   });
  71.                         }
  72.           });

  73.         </script>
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-4 17:33 , Processed in 0.083591 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表