详解vue开发中调用微信jssdk的问题
起因
微信分享网址时无法分享图片,这个问题需要用jssdk去解决。其实开始的时候时可以看到图片的,但后来微信禁止了。所以只能使用jssdk去解决。
普通网页开发很简单,但是使用vue或其他前端框架开发spa单页面webapp的时候就会有问题了。只要url发生变化就会报签名错误。其实微信官方上已经写了说明。
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的webapp可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现webapp的页面会导致签名失败,此问题会在Android6.2中修复)。
但这些说明然并卵(然而并没有什么卵用)。
问题根源
1同一个url仅需调用一次,对于变化url的SPA的webapp可在每次url变化时进行调用
如果你的链接时采用hash方式,锚点变了也要重新调用,因为url发生了变化,这一点可以放在router的监听事件中比如watch一下$route,或者使用2.2中引入的beforeRouteUpdate守卫。
2生成签名时url中不能包含锚点
微信jssdk的签名是需要服务端来生成的,所以我们需要将当前页面的网址传递给服务端,由服务端生成wx.config初始化所需要的参数。
但是url传递的时候需要注意,一定一定一定不能带有锚点链接。可以使用location.href.split(‘#')[0]获取url中锚点之前的部分。
比如你的网址是http://domain.com/index.html#/food/1
你只需要把http://domain.com/index.html传递到服务端,让服务端生成签名就可以了,你在调用jssdk的时候可以把url后面添加锚点链接。
实例
安装jssdk
npminstallweixin-js-sdk--save
前段代码
exportdefault{ mounted(){ this.$nextTick(function(){ this.getConfig() }) }, data(){ return{ detail:[], } }, methods:{ //微信分参数 getConfig(){ leturl=location.href.split('#')[0]//获取锚点之前的链接 this.$http.get('/index.php',{ params:{ url:url } }).then(response=>{ letres=response.data; this.wxInit(res); }) }, //微信分享 wxInit(res){ leturl=location.href.split('#')[0]//获取锚点之前的链接 letlinks=url+'#/Food/'+this.$route.params.id; lettitle=this.detail.name+'-嘌呤查'; letdesc='了解更多知识,请关注“嘌呤查”公众号'; letimgUrl=this.thumb; wx.config({ debug:false, appId:res.appId, timestamp:res.timestamp, nonceStr:res.nonceStr, signature:res.signature, jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] }); wx.ready(function(){ wx.onMenuShareTimeline({ title:title,//分享标题 desc:desc,//分享描述 link:links,//分享链接 imgUrl:imgUrl,//分享图标 success:function(){ //alert("分享到朋友圈成功") //Toast({ //message:"成功分享到朋友圈" //}); }, cancel:function(){ //alert("分享失败,您取消了分享!") //Toast({ //message:"分享失败,您取消了分享!" //}); } }); //微信分享菜单测试 wx.onMenuShareAppMessage({ title:title,//分享标题 desc:desc,//分享描述 link:links,//分享链接 imgUrl:imgUrl,//分享图标 success:function(){ //alert("成功分享给朋友") //Toast({ //message:"成功分享给朋友" //}); }, cancel:function(){ //alert("分享失败,您取消了分享!") //Toast({ //message:"分享失败,您取消了分享!" //}); } }); wx.onMenuShareQQ({ title:title,//分享标题 desc:desc,//分享描述 link:links,//分享链接 imgUrl:imgUrl,//分享图标 success:function(){ //alert("成功分享给QQ") //Toast({ //message:"成功分享到QQ" //}); }, cancel:function(){ //alert("分享失败,您取消了分享!") //Toast({ //message:"分享失败,您取消了分享!" //}); } }); wx.onMenuShareWeibo({ title:title,//分享标题 desc:desc,//分享描述 link:links,//分享链接 imgUrl:imgUrl,//分享图标 success:function(){ //alert("成功分享给朋友") //Toast({ //message:"成功分享到腾讯微博" //}); }, cancel:function(){ //alert("分享失败,您取消了分享!") //Toast({ //message:"分享失败,您取消了分享!" //}); } }); wx.onMenuShareQZone({ title:title,//分享标题 desc:desc,//分享描述 link:links,//分享链接 imgUrl:imgUrl,//分享图标 success:function(){ //alert("成功分享给朋友") //Toast({ //message:"成功分享到QQ空间" //}); }, cancel:function(){ //alert("分享失败,您取消了分享!") //Toast({ //message:"分享失败,您取消了分享!" //}); } }); }); wx.error(function(err){ alert(JSON.stringify(err)) }); } } }
index.php页面代码
//官方实例,生成wx.config需要的配置信息 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=!empty($_GET['url'])?$_GET['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
看到上面的类中使用$_GET[‘url']接收前段传过来的数据
以上所述是小编给大家介绍的vue开发中调用微信jssdk的问题详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!