实现的功能:
1、网址生成二维码
2、微信扫描二维码,打开网址
3、微信APP右上角点击弹出菜单分享
4、分享内容可自定义:标题、描述、链接、图片
普通分享显示图:
接口分享显示图
微信公众平台文档地址:
微信网页开发–>微信JS-SDK说明文档
公众平台文档
在 微信JS-SDK说明文档 页面最底部,有示例代码(可以直接点击以下链接下载,也可去微信分享文档底部查找)
示例代码
文档内没有 .NET 版本的分享示例代码(原因所在)
好吧,开始一段文字内容(其实在微信文档里面复制的文字):
概述
微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。
通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
此文档面向网页开发者介绍微信JS-SDK如何使用及相关注意事项。
JSSDK使用步骤(微信文档里看吧)
大致就是说:要先配置参数,然后再使用相关接口
开始使用部分
NeedSharePage.aspx 页面
<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js" type="text/javascript"></script>
<script type="text/javascript">
//配置你的微信配置信息wx.config({debug: false, // 是否开启调试模式,调试请改为trueappId: '<%=appid %>', // 必填,公众号的唯一标识timestamp: '<%=timestamp %>', // 必填,生成签名的时间戳nonceStr: '<%=nonceStr %>', // 必填,生成签名的随机串signature: '<%=signature %>', // 必填,签名,见附录1jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareQZone'] // 必填,需要使用的JS接口列表,此处定义你需要的接口,所有JS接口列表见附录2});// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。wx.ready(function(){//如果使用自定义按钮点击事件来分享,则不需要在ready内调用//这里我没有使用自定义按钮,所以需要在ready内调用//wx.checkJsApi判断当前客户端版本是否支持指定JS接口,备注:checkJsApi接口是客户端6.0.2新引入的一个预留接口,第一期开放的接口均可不使用checkJsApi来检测。wx.checkJsApi({jsApiList: ['getLocation','onMenuShareTimeline','onMenuShareAppMessage'],success: function (res) {alert(JSON.stringify(res));}});// 分享到朋友圈wx.onMenuShareTimeline({title: '<%=title %>', // 分享标题link: '<%=link %>', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致imgUrl: '<%=imgUrl %>', // 分享图标success: function () {// 用户确认分享后执行的回调函数(可以进行分享数+1操作)//alert('分享成功');},cancel: function () {// 用户取消分享后执行的回调函数// alert(22);}});//分享给朋友、分享给QQ、分享QQ空间等都差不多,此处不再写了。
});
</script>
签名的生成
(微信文档内,可见 :附录1-JS-SDK使用权限签名算法)
jsapi_ticket
生成签名之前必须先了解一下jsapi_ticket。
jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。
由于获取jsapi_ticket的api**调用次数非常有限**,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务
全局缓存jsapi_ticket 。
1.参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):../15/54ce45d8d30b6bf6758f68d2e95bc627.html
(官方给的这个地址,我也是忍不住吐槽,根本找不到在哪里)
获取Token的地址为:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPsecret
参数:
appid=公众号的APPID
secret=公众号密钥
使用GET 请求,请求此地址。返回参数为:
{
“expires_in”:7200,
“access_token”:”xxxxxxxxxxxxxxxx”
}
2.用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket
(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
返回参数为:
{
“errcode”:0,
“errmsg”:”ok”,
“ticket”:”xxxxxxxxxxxxxx”,
“expires_in”:7200
}
3.获取到 JSAPI_TICKET 后,就可以使用签名算法进行签名了。
签名生成规则如下:参与签名的字段包括
noncestr, //随机字符串
jsapi_ticket, //有效的jspi_ticket
timestamp,//时间戳
url //当前网页的URL,不包含#及其后面部分
。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
步骤1.
string1=jsapi_ticket=xxxxxxx&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
步骤2. 对string1进行sha1签名,得到signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed
注意事项
1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
2.签名用的url必须是调用JS接口页面的完整URL。
3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。
如出现invalid signature 等错误详见附录5常见错误及解决办法。
生成后的签名拿去校验:
微信 JS 接口签名校验工具
以下为自定义的分享类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WxPayAPI;
using System.Web;
using System.Web.Caching;
using Utils.Validate;namespace Utils.WxPayAPI
{public class WxShareApi{/// <summary>/// 2根据 token 获取jsapi_ticket/// </summary>/// <param name="access_token">token</param>/// <returns>jsapi_ticket</returns>private string Get_Jsapi_Ticket(){if (CacheClass.GetCache("jsapiticket") != null){return CacheClass.GetCache("jsapiticket").ToString();}StringBuilder sb = new StringBuilder();sb.Append(WxPayConfig.GetJsApiTicketUrl).Append("?").Append("access_token=").Append(Get_Token()).Append("&").Append("type=jsapi");string jsapi_ticket = HttpService.Get(sb.ToString());JsapiTicket jsapiTicketObject = LitJson.JsonMapper.ToObject<JsapiTicket>(jsapi_ticket);CacheClass.SetCache("jsapiticket", jsapiTicketObject.ticket);return jsapiTicketObject.ticket;}/// <summary>/// 1获取微信分享需要的Token/// </summary>/// <param name="APPID">公众号APPID</param>/// <param name="APPSECRET">公众号APPSECRET</param>/// <returns>token</returns>private string Get_Token(){if (CacheClass.GetCache("token") != null){return CacheClass.GetCache("token").ToString();}StringBuilder sb = new StringBuilder();sb.Append(WxPayConfig.GetTokenUrl).Append("&").Append("appid=").Append(WxPayConfig.APPID).Append("&").Append("secret=").Append(WxPayConfig.APPSECRET);string token = HttpService.Get(sb.ToString());TokenObject tokenObject = LitJson.JsonMapper.ToObject<TokenObject>(token);CacheClass.SetCache("token", tokenObject.access_token);return tokenObject.access_token;}/// <summary>/// 3生成微信分享签名/// </summary>/// <param name="ticket">jsapiticket</param>/// <param name="noncestr">随机串</param>/// <param name="timestamp">时间戳</param>/// <returns>SHA1加密签名</returns>public string GenerateJSSDKSign(string noncestr, string timestamp){StringBuilder sb = new StringBuilder();sb.Append("jsapi_ticket=").Append(Get_Jsapi_Ticket()).Append("&").Append("noncestr=").Append(noncestr).Append("&").Append("timestamp=" + timestamp).Append("&");string url = HttpContext.Current.Request.Url.AbsoluteUri;sb.Append("url=" + url);string sign = EncodeHelper.SHA1(sb.ToString(), Encoding.UTF8);Log.Info("sign" + DateTime.Now, sign);return sign;}}//jsapipublic class JsapiTicket{public int errcode { get; set; }public string errmsg { get; set; }public string ticket { get; set; }public int expires_in { get; set; }}//tokenpublic class TokenObject{public int expires_in { get; set; }public string access_token { get; set; }}
}
使用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Share
{public partial class NeedSharePage : System.Web.UI.Page{//wx share configpublic string appid = WxPayConfig.APPID;public string timestamp = "";public string nonceStr = "";public string signature = "";public string title = "";public string description = "";public string imgUrl = "";public string link = "";protected void Page_Load(object sender, EventArgs e){//微信分享需要的数值 begin -----------------------timestamp = WxPayApi.GenerateTimeStamp();nonceStr = WxPayApi.GenerateNonceStr();title ="测试";description = "测试描述";imgUrl = "测试图片";link = HttpContext.Current.Request.Url.AbsoluteUri;//根据jsapi获取signWxShareApi share = new WxShareApi();signature = share.GenerateJSSDKSign(nonceStr, timestamp);//微信分享需要的数值 end ---------------------------}}
}