javascript获取wx.config内部字段解决微信分享


Posted in Javascript onMarch 09, 2016

背景
在微信分享开发的时候我们通常的流程是

<?php
 require_once "jssdk.php";
 $jssdk = new JSSDK("yourAppID", "yourAppSecret");
 $signPackage = $jssdk->GetSignPackage();
?>
 <!DOCTYPE html>
 <html lang="en">
 <head>
 <meta charset="UTF-8">
 <title>微信分享</title>
 </head>
 <body>
 </body>
 <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
 <script>
 wx.config({
 appId: '<?php echo $signPackage["appId"];?>',
 timestamp: <?php echo $signPackage["timestamp"];?>,
 nonceStr: '<?php echo $signPackage["nonceStr"];?>',
 signature: '<?php echo $signPackage["signature"];?>',
 jsApiList: ['onMenuShareTimeline'
 'onMenuShareAppMessage'
 ]
 });

 wx.ready(function() {
 
 wx.onMenuShareTimeline({
 title: '', // 分享标题
 link: '', // 分享链接
 imgUrl: '', // 分享图标
 success: function() {
 // 用户确认分享后执行的回调函数
 },
 cancel: function() {
 // 用户取消分享后执行的回调函数
 }
 });

 wx.onMenuShareAppMessage({
 title: '', // 分享标题
 desc: '', // 分享描述
 link: '', // 分享链接
 imgUrl: '', // 分享图标
 type: '', // 分享类型,music、video或link,不填默认为link
 dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
 success: function() {
 // 用户确认分享后执行的回调函数
 },
 cancel: function() {
 // 用户取消分享后执行的回调函数
 }
 });

 });
 </script>

 </html>

上面是一个php文件,这样的代码的一个很大缺点是前后端未分离耦合度太高,再一就是混合写不是很美观,所以我们要让PHP和HTML分离,要实现分享功能,首先就是要调用用微信的jssdk Api获取到配置参数, 这个必须是要通过php后台语言来获取的,然后将这些参数配置于wx.config中,在wx.config之前要先引入http://res.wx.qq.com/open/js/jweixin-1.0.0.js 然后就可以写分享的函数了,他们的依赖关系是wx.config 需要js库和config内部的参数,分享依赖wx.config
所以最重要的就把php的配置参数分离出来单独获取即可

解决方案
将获取配置参数的PHP写作为接口,在js里使用ajax调用,获取参数并转换为对象,再通过回调函数将ajax获取的参数塞到wx.config中

代码结构及功能

javascript获取wx.config内部字段解决微信分享

  • index.html 页面入口
  • weixin.php 服务器端获取配置参数
  • configdata.php将配置转为借口输出
  • getconfig.js 用ajax获取configdata.php的数据
  • share.js 分享回调函
  • webpack.config.js webpack配置文件
  • index.js 打包后最终html调用js文件

index.html html静态文件

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>静态页面微信分享测试</title>
</head>
<body>
 <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
 <script src="statics/js/index.js"></script>
</body>
</html>

configdata.php 后台获取配置的参数 注意url要写上自己被分享的页面url不然会报invalid signature错误

<?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 = "http://$_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 = json_decode(file_get_contents("jsapi_ticket.json"));
 if ($data->expire_time < time()) {
 $accessToken = $this->getAccessToken();
 $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;
 $fp = fopen("jsapi_ticket.json", "w");
 fwrite($fp, json_encode($data));
 fclose($fp);
 }
 } else {
 $ticket = $data->jsapi_ticket;
 }

 return $ticket;
 }

 private function getAccessToken() {
 // access_token 应该全局存储与更新,以下代码以写入到文件中做示例
 $data = json_decode(file_get_contents("access_token.json"));
 if ($data->expire_time < time()) {
 $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;
 $fp = fopen("access_token.json", "w");
 fwrite($fp, json_encode($data));
 fclose($fp);
 }
 } else {
 $access_token = $data->access_token;
 }
 return $access_token;
 }

 private function httpGet($url) {
 $curl = curl_init();
 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
 curl_setopt($curl, CURLOPT_TIMEOUT, 500);
 curl_setopt($curl, CURLOPT_URL, $url);

 $res = curl_exec($curl);
 curl_close($curl);

 return $res;
 }
}

weixin.php 将配置参数格式化输出

<?php

 require_once "weixin.php";
 $jssdk = new JSSDK(appId, appSecretecret);
 $signPackage = $jssdk->GetSignPackage();
 
 class Config{ 
 var $appId; 
 var $timestamp; 
 var $nonceStr; 
 var $signature; 
 var $url;
 } 
 
 $config = new Config(); 
 
 $config -> appId = $signPackage["appId"]; 
 $config -> timestamp = $signPackage["timestamp"]; 
 $config -> nonceStr = $signPackage["nonceStr"]; 
 $config -> signature = $signPackage["signature"];
 $config -> url = $signPackage["url"]; 
 
 echo json_encode($config);
?>

getconfig.js 使用ajax获取接口数据(配置参数)

var getConfig = function(callback) {
 $.ajax({
 url: "http://www.goxueche.com/api/configdata.php",
 type: "get",
 success: function(data) {
 callback(data);
 }
 })
}

module.exports = getConfig;

share.js 分享函数

var getWeixincofig = require("./getconfig.js");
getWeixincofig(shareweixin);


function shareweixin(data) {

 var data = JSON.parse(data);
 console.log(data);

 window.wx.config({
 debug:true,
 appId: data.appId,
 timestamp: data.timestamp,
 nonceStr: data.nonceStr,
 signature: data.signature,
 jsApiList: ['checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage']
 });

 wxShare();
}

function wxShare() {
 //检测api是否生效
 wx.ready(function() {
 wx.checkJsApi({
 jsApiList: [
 'getNetworkType',
 'previewImage'
 ],
 success: function(res) {
 console.log(JSON.stringify(res));
 }
 });
 //分享给好友
 wx.onMenuShareAppMessage({
 title: '趣学车-有温度的互联网驾校',
 desc: '想去学车,就趣学车!',
 link: 'http://www.goxueche.com',
 imgUrl: 'http://www.goxueche.com/....png'
 });
 
 //分享到朋友圈
 wx.onMenuShareTimeline({
 title: '趣学车-有温度的互联网驾校',
 desc: '想去学车,就趣学车!',
 link: 'http://www.goxueche.com',
 imgUrl: 'http://www.goxueche.com/....png'
 });

 });
}

webpack.config.js

var webpack = require('webpack'); 
module.exports = { 
 entry: {
 index: './share.js',
 },
 output: {
 path: './',
 filename: '[name].js'
 }
};

本文已被整理到了《JavaScript微信开发技巧汇总》,欢迎大家学习阅读。

为大家推荐现在关注度比较高的微信小程序教程一篇:《微信小程序开发教程》小编为大家精心整理的,希望喜欢。

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
jQuery的三种$()
Dec 30 Javascript
js获取指定日期前后的日期代码
Aug 20 Javascript
xmlhttp缓存清除的2种解决方法
Dec 13 Javascript
javascript中parentNode,childNodes,children的应用详解
Dec 17 Javascript
贴近用户体验的Jquery日期、时间选择插件
Aug 19 Javascript
js简单网速测试方法完整实例
Dec 15 Javascript
JQuery插件Marquee.js实现无缝滚动效果
Apr 26 Javascript
Vue过滤器的用法和自定义过滤器使用
Feb 08 Javascript
Layer弹出层动态获取数据的方法
Aug 20 Javascript
Electron + vue 打包桌面操作流程详解
Jun 24 Javascript
详解vuejs中执行npm run dev出现页面cannot GET/问题
Apr 26 Javascript
Javascript如何递归遍历本地文件夹
Aug 06 Javascript
js仿支付宝填写支付密码效果实现多方框输入密码
Mar 09 #Javascript
jquery实现文本框textarea自适应高度
Mar 09 #Javascript
分享12个实用的jQuery代码片段
Mar 09 #Javascript
详解JavaScript正则表达式之分组匹配及反向引用
Mar 09 #Javascript
javascript html5移动端轻松实现文件上传
Mar 27 #Javascript
javascript事件绑定学习要点
Mar 09 #Javascript
js实现分割上传大文件
Mar 09 #Javascript
You might like
php 获取本机外网/公网IP的代码
2010/05/09 PHP
web目录下不应该存在多余的程序(安全考虑)
2012/05/09 PHP
php 模拟 asp.net webFrom 按钮提交事件的思路及代码
2013/12/02 PHP
PHP strip_tags()去除HTML、XML以及PHP的标签介绍
2014/02/18 PHP
详解yii2实现分库分表的方案与思路
2017/02/03 PHP
Laravel中服务提供者和门面模式的入门介绍
2017/11/06 PHP
JavaScript实现找出数组中最长的连续数字序列
2014/09/03 Javascript
浅谈javascript 函数属性和方法
2015/01/21 Javascript
七夕情人节丘比特射箭小游戏
2015/08/20 Javascript
五种js判断是否为整数类型方式
2015/12/03 Javascript
Listloading.js移动端上拉下拉刷新组件
2016/08/04 Javascript
纯JS实现表单验证实例
2016/12/24 Javascript
angular2系列之路由转场动画的示例代码
2017/11/09 Javascript
Node.js readline 逐行读取、写入文件内容的示例
2018/03/01 Javascript
react 父子组件之间通讯props
2018/09/08 Javascript
js+canvas实现两张图片合并成一张图片的方法
2019/11/01 Javascript
解决vue 使用setTimeout,离开当前路由setTimeout未销毁的问题
2020/07/21 Javascript
three.js 如何制作魔方
2020/07/31 Javascript
python采用django框架实现支付宝即时到帐接口
2016/05/17 Python
Python基于回溯法子集树模板解决全排列问题示例
2017/09/07 Python
Django-Rest-Framework 权限管理源码浅析(小结)
2018/11/12 Python
Python实现繁?转为简体的方法示例
2018/12/18 Python
Django Form 实时从数据库中获取数据的操作方法
2019/07/25 Python
关于Python内存分配时的小秘密分享
2019/09/05 Python
Python 获取项目根路径的代码
2019/09/27 Python
python 实现朴素贝叶斯算法的示例
2020/09/30 Python
Expedia西班牙:预订酒店、机票、旅行和廉价度假套餐
2019/04/10 全球购物
Ibatis如何调用存储过程
2015/05/15 面试题
介绍一下Linux文件的记录形式
2012/04/18 面试题
软件工程师面试题
2012/06/25 面试题
大学生年度自我鉴定
2013/10/31 职场文书
分公司经理任命书
2014/06/05 职场文书
干部职工纪律作风整改措施思想汇报
2014/10/11 职场文书
瞿秋白纪念馆观后感
2015/06/10 职场文书
和谐拯救危机观后感
2015/06/15 职场文书
SpringBoot 拦截器妙用你真的了解吗
2021/07/01 Java/Android