详解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的问题详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!