微信分享
当有微信推广活动和页面的时候都会用到微信分享,本文介绍如何在页面上处理微信分享,使用的是js+C#.NET语言。
原理
大体流程是这样的:
- 绑定域名
- 列表内容
- 引入JS文件
- 通过config接口注入权限验证配置
- 通过ready接口处理成功验证
- 通过error接口处理失败验证
- 编写对应回调
实现
当然可以结合官网文档一起看
- 绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
备注:登录后可在“开发者中心”查看对应的接口权限。
- 引入JS文件
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js
备注:支持使用 AMD/CMD 标准模块加载方法加载
- 通过config接口注入权限验证配置
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名,见附录1
jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
这里可以使用ajax请求服务端,返回需要的一些签名信息:
$.ajax({
type: "get",
url: "getwxfxSign.ashx?url=" + encodeURIComponent(location.href.split('#')[0]),
success: function (data) {
if (data != null) {
data = JSON.parse(data);
var timeStamp = data.timeStamp;
var nonceStr = data.nonceStr;
var signature = data.signature;
wxfxConfig.timeStamp = timeStamp;
wxfxConfig.nonceStr = nonceStr;
wxfxConfig.signature = signature;
wxfxConfig.zm_title = "";
wxfxConfig.zm_summary = "";
wxfxConfig.zm_share = "";
wxfxConfig.init();
}
}
})
确保你获取用来签名的url是动态获取的,前端需要用js获取当前页面除去’#’hash部分的链接(可用location.href.split(‘#’)[0]获取,而且需要encodeURIComponent),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。
wxfxConfig.js
var wxfxConfig = {
timeStamp: '',
nonceStr: '',
signature: '',
zm_title: '',
zm_summary: '',
zm_share: '',
zm_imgurl:'',
wxconfig: function () {
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: wxfxConfig.timeStamp, // 必填,生成签名的时间戳
nonceStr: wxfxConfig.nonceStr, // 必填,生成签名的随机串
signature: wxfxConfig.signature, // 必填,签名,见附录1
jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
},
wxready: function () {
wx.ready(function () {
wx.onMenuShareTimeline({
title: wxfxConfig.zm_title,//分享标题
desc: wxfxConfig.zm_summary,//分享摘要
link: wxfxConfig.zm_share,//分享链接
imgUrl: wxfxConfig.zm_imgurl,//分享图片
trigger: function (res) {
},
success: function (res) {
},
cancel: function (res) {
},
fail: function (res) {
alert(JSON.stringify(res));
}
});
wx.onMenuShareAppMessage({
title: wxfxConfig.zm_title,
desc: wxfxConfig.zm_summary,
link: wxfxConfig.zm_share,
imgUrl: wxfxConfig.zm_imgurl,
trigger: function (res) {
},
success: function (res) {
},
cancel: function (res) {
},
fail: function (res) {
alert(JSON.stringify(res));
}
});
//新加分享到qq,微博,qq空间
wx.onMenuShareQQ({
title: wxfxConfig.zm_title,
desc: wxfxConfig.zm_summary,
link: wxfxConfig.zm_share,
imgUrl: wxfxConfig.zm_imgurl,
success: function (res) {
},
cancel: function (res) {
},
fail: function (res) {
alert(JSON.stringify(res));
}
});
wx.onMenuShareWeibo({
title: wxfxConfig.zm_title,
desc: wxfxConfig.zm_summary,
link: wxfxConfig.zm_share,
imgUrl: wxfxConfig.zm_imgurl,
success: function (res) {
},
cancel: function (res) {
},
fail: function (res) {
alert(JSON.stringify(res));
}
});
wx.onMenuShareQZone({
title: wxfxConfig.zm_title,
desc: wxfxConfig.zm_summary,
link: wxfxConfig.zm_share,
imgUrl: wxfxConfig.zm_imgurl,
success: function (res) {
},
cancel: function (res) {
},
fail: function (res) {
alert(JSON.stringify(res));
}
});
});
},
wxerror: function () {
wx.error(function (res) {
alert("接口验证失败,详细信息:\n" + JSON.stringify(res));
});
},
init: function () {
wxfxConfig.wxconfig();
wxfxConfig.wxready();
wxfxConfig.wxerror();
}
}
getwxfxSign.ashx处理程序
using System;
using System.Web;
using System.Collections.Generic;
public class getwxfxSign : IHttpHandler {
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
if (string.IsNullOrEmpty(HttpContext.Current.Request.QueryString["url"]))
{
return;
}
string timeStamp = string.Empty;
string nonceStr = string.Empty;
string signature = string.Empty;
nonceStr = CreateNoncestr();//16位随机字符串
timeStamp = GetTimeStamp();//时间戳
string url = HttpContext.Current.Request.QueryString["url"];
string jsapiTicket = GetJsapiTicket();//获取jsapi_ticket
Dictionary<string, string> signData = new Dictionary<string, string>() {
{"noncestr",nonceStr},
{"jsapi_ticket",jsapiTicket},
{"timestamp",timeStamp},
{"url",url}
};
signature = Sign(signData);
context.Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(new { timeStamp = timeStamp, nonceStr = nonceStr, signature = signature }));
}
public bool IsReusable {
get {
return false;
}
}
}
获取随机字符串:
public static String CreateNoncestr()
{
String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
String res = "";
Random rd = new Random();
for (int i = 0; i < 16; i++)
{
res += chars[rd.Next(chars.Length - 1)];
}
return res;
}
获取jsapi_ticket可以参考这里