400字范文,内容丰富有趣,生活中的好帮手!
400字范文 > java 微信分享朋友圈 链接显示图片_【微信开发】-- 微信分享功能(分享到朋友和朋

java 微信分享朋友圈 链接显示图片_【微信开发】-- 微信分享功能(分享到朋友和朋

时间:2018-11-07 21:06:27

相关推荐

java 微信分享朋友圈 链接显示图片_【微信开发】-- 微信分享功能(分享到朋友和朋

想在微站里面实现分享帖子给朋友和朋友圈,显示图片和简介,就这么简单的功能折腾了1星期。。。主要是微信官方文档没看清楚,怪自己了。

遇到invalid signature签名错误。找了半天,各种调试,终于找到问题了,每个新闻的id是变动的,

url需要传入完整的地址,在微信官方手册里面查到的。

比如页面是/wx.aspx?id=111,需要完整传入,不能仅仅在url里面传入/wx.aspx

下面是stoneniqiu 的具体做法,大家可以参考一下。

内嵌在微信中的网页,右上角都会有一个默认的分享功能。如下图所示,第一个为自定义的效果,第二个为默认的效果。实现了自定义的分享链接是不是更让人有点击的欲望?下面讲解下开发的过程。

一、准备,设置js接口安全域名

这需要使用微信的jssdk,先需要在微信公众号后台进行设置:公众号设置-->功能设置-->JS接口安全域名。打开这个页面之后你会看到下面的提示。需要先下载这个文件并上传到指定域名的根目录。

这个文件里面是一个字符串,从名称看是用来校验用的。先上传了这个文件,你才能保存成功。这样你就可以使用jssdk了。

二、前端配置

首先要说明的是分享功能是一个配置功能,绑定在按钮的click事件中是没有效果的。也就是说只有点击右上角的分享才有效果(有的文字内容分享不知道是怎么实现的)。官方的js有四个步骤,首先是引入jssdk:

根据官方的配置参数,我们可以定义一个WXShareModel对象:

public class WXShareModel

{

public string appId { get; set; }

public string nonceStr { get; set; }

public long timestamp { get; set; }

public string signature { get; set; }

public string ticket { get; set; }

public string url { get; set; }

public void MakeSign()

{

var string1Builder = new StringBuilder();

string1Builder.Append("jsapi_ticket=").Append(ticket).Append("&")

.Append("noncestr=").Append(nonceStr).Append("&")

.Append("timestamp=").Append(timestamp).Append("&")

.Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url);

var string1 = string1Builder.ToString();

signature = Util.Sha1(string1, Encoding.Default);

}

}

然后是进行配置:

wx.config({

debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。

appId: '@Model.appId', // 必填,公众号的唯一标识

timestamp: '@Model.timestamp', // 必填,生成签名的时间戳

nonceStr: '@Model.nonceStr', // 必填,生成签名的随机串

signature: '@Model.signature',// 必填,签名,见附录1

jsApiList: ["checkJsApi", "onMenuShareTimeline", "onMenuShareAppMessage", "onMenuShareQQ", "onMenuShareQZone"] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2

});

wx.ready(function () {

document.querySelector('#checkJsApi').onclick = function () {

wx.checkJsApi({

jsApiList: [

'getNetworkType',

'previewImage'

],

success: function (res) {

alert(JSON.stringify(res));

}

});

};

//朋友圈

wx.onMenuShareTimeline({

title: '暖木科技', // 分享标题

link: '/home/lampindex', // 分享链接

imgUrl: '/images/s1.jpg',

success: function (res) {

alert('已分享');

},

cancel: function (res) {

alert('已取消');

},

fail: function (res) {

alert(JSON.stringify(res));

}

});

//朋友

wx.onMenuShareAppMessage({

title: '暖木科技', // 分享标题

desc: '宝宝的睡眠很重要,你的睡眠也很重要', // 分享描述

link: '/home/lampindex', // 分享链接

imgUrl: '/images/s1.jpg', // 分享图标

type: '', // 分享类型,music、video或link,不填默认为link

dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空

success: function () {

// 用户确认分享后执行的回调函数

alert("分享");

},

cancel: function () {

// 用户取消分享后执行的回调函数

alert("取消分享");

}

});

});

然后剩下就是后端的事情了。后端的关键是获取access_token和jsapi_ticket以及生成正确的签名。另外如果要统计分享的数量,最好就是在success方法中进行统计了。

三、生成签名

1.access_token

获取access_token方法全平台都是一致的。

public const string AccessTokenUrl = "https://api./cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";

public TokenResult GetAccessToken()

{

var url = string.Format(WxDeviceConfig.AccessTokenUrl, WxDeviceConfig.AppId, WxDeviceConfig.APPSECRET);

var res = SendHelp.Send(null, url, null, CommonJsonSendType.GET);

return res;

}

access_token的超时时间是7200秒,所以先可以缓存起来。SendHelp文章末尾可下载

2.获取jsapi_ticket

access_token的作用就是为了获取jsapi_ticket。用get方式获取,url:https://api./cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi,返回的JSON对象如下。

{

"errcode":0,

"errmsg":"ok",

"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",

"expires_in":7200

}

所以可以定义一个模型:

public class jsapiTicketModel

{

public string errcode { get; set; }

public string errmsg { get; set; }

public string ticket { get; set; }

public string expires_in { get; set; }

}

再完成获取ticket的方法:

public jsapiTicketModel GetJsApiTicket(string accessToken)

{

var url = string.Format(WxPayConfig.Jsapi_ticketUrl, accessToken);

return SendHelp.Send(accessToken, url, "", CommonJsonSendType.GET);

}

ticket过期时间也是7200秒,并且不能频繁的请求,所以也需要再服务端缓存起来。

private void setCacheTicket(string cache)

{

_cacheManager.Set(tokenKey, cache, 7200);

}

MemoryCacheManager:

View Code

3.签名

终于到这一步了,然后你在文档中看到让你失望的一幕:

么有C#的demo,支付那边都提供了,为啥jssdk没有提供,好吧先不吐槽了。官方也说明白签名的规则。一开始我使用的是/night-king/weixinSDK中的签名:

public static string Sha1(string orgStr, string encode = "UTF-8")

{

var sha1 = new SHA1Managed();

var sha1bytes = System.Text.Encoding.GetEncoding(encode).GetBytes(orgStr);

byte[] resultHash = puteHash(sha1bytes);

string sha1String = BitConverter.ToString(resultHash).ToLower();

sha1String = sha1String.Replace("-", "");

return sha1String;

}//错误示例

得出的结果和官方校验的不一致,一直提示签名错误。

正确的写法是:

public static string Sha1(string orgStr, Encoding encode)

{

SHA1 sha1 = new SHA1CryptoServiceProvider();

byte[] bytes_in = encode.GetBytes(orgStr);

byte[] bytes_out = puteHash(bytes_in);

sha1.Dispose();

string result = BitConverter.ToString(bytes_out);

result = result.Replace("-", "");

return result;

}

和官方校验的结果一直后,就ok了(忽略大小写)。另外一个需要注意的地方是签名中的url。如果页面有参数,model中的url也需要带参数,#号后面的不要。不然也是会报签名错误。

public ActionResult H5Share()

{

var model = new WXShareModel();

model.appId = WxPayConfig.APPID;

model.nonceStr = WxPayApi.GenerateNonceStr();

model.timestamp = Util.CreateTimestamp();

model.ticket = GetTicket();

model.url = "/AuthWeiXin/share";// domain + Request.Url.PathAndQuery;

model.MakeSign();

Logger.Debug("获取到ticket:" + model.ticket);

Logger.Debug("获取到签名:" + model.signature);

return View(model);

}

四、小结

wx.config中的debug为true会alert各种操作结果。参数正确之后界面会提示:

至此,分享的功能就ok了。也就打开了调用其他jssdk的大门。另外文中的SendHelp对象是用的Senparc(基于.net4.5)的dll。

参考资料:

我的核心代码

[System.Web.Services.WebMethod]public static WXShareModel GetKey(stringstr)

{

WXShareModel aModel= newWXShareModel();

WXToolsHelper tb= newWXToolsHelper();string AppId = "你的APPID";string secret = "你的secret";string access_token =tb.GetAccess_Token(AppId, secret);

aModel.appId=AppId;

aModel.nonceStr=tb.CreatenNonce_str();

aModel.timestamp=tb.CreatenTimestamp();

aModel.ticket=tb.GetTicket(access_token);

aModel.url=str;

aModel.MakeSign();returnaModel;

}public classWXShareModel

{public string appId { get; set; }public string nonceStr { get; set; }public long timestamp { get; set; }public string ticket { get; set; }public string url { get; set; }public string signature { get; set; }public voidMakeSign()

{var string1Builder = newStringBuilder();

string1Builder.Append("jsapi_ticket=").Append(ticket).Append("&")

.Append("noncestr=").Append(nonceStr).Append("&")

.Append("timestamp=").Append(timestamp).Append("&")

.Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url);var string1 =string1Builder.ToString();

signature=Sha1(string1, Encoding.Default);

}public static string Sha1(stringorgStr, Encoding encode)

{

SHA1CryptoServiceProvider sha1= newSHA1CryptoServiceProvider();byte[] bytes_in =encode.GetBytes(orgStr);byte[] bytes_out =puteHash(bytes_in);

sha1.Dispose();string result =BitConverter.ToString(bytes_out);

result= result.Replace("-", "");returnresult;

}public classWXToolsHelper

{///

///获取全局的access_token,程序缓存///

/// 第三方用户唯一凭证

/// 第三方用户唯一凭证密钥,即appsecret

/// 得到的全局access_token

public string GetAccess_Token(string AppId, stringAppSecret)

{try{//先查缓存数据

if (HttpContext.Current.Cache["access_token"] != null)

{return HttpContext.Current.Cache["access_token"].ToString();

}else{returnGetToken(AppId, AppSecret);

}

}catch{returnGetToken(AppId, AppSecret);

}

}///

///获取全局的access_token///

/// 第三方用户唯一凭证

/// 第三方用户唯一凭证密钥,即appsecret

/// 得到的全局access_token

public string GetToken(string AppId, stringAppSecret)

{var client = .WebClient();

client.Encoding=System.Text.Encoding.UTF8;var url = string.Format("https://api./cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", AppId, AppSecret);var data =client.DownloadString(url);var jss = newJavaScriptSerializer();var access_tokenMsg = jss.Deserialize>(data);//放入缓存中

HttpContext.Current.Cache.Insert("access_token", access_tokenMsg["access_token"], null, DateTime.Now.AddSeconds(7100), TimeSpan.Zero, CacheItemPriority.Normal, null);//清除jsapi_ticket缓存

HttpContext.Current.Cache.Remove("ticket");//获取jsapi_ticket,为了同步

GetTicket(access_tokenMsg["access_token"].ToString());return access_tokenMsg["access_token"].ToString();

}///

///获取jsapi_ticket,程序缓存///

/// 全局的access_token

/// 得到的jsapi_ticket

public string GetJsapi_Ticket(stringaccess_token)

{try{//先查缓存数据

if (HttpContext.Current.Cache["ticket"] != null)

{return HttpContext.Current.Cache["ticket"].ToString();

}else{returnGetTicket(access_token);

}

}catch{returnGetTicket(access_token);

}

}///

///获取jsapi_ticket///

/// 全局的access_token

/// 得到的jsapi_ticket

public string GetTicket(stringaccess_token)

{var client = .WebClient();

client.Encoding=System.Text.Encoding.UTF8;var url = string.Format("https://api./cgi-bin/ticket/getticket?access_token={0}&type=jsapi", access_token);var data =client.DownloadString(url);var jss = newJavaScriptSerializer();var ticketMsg = jss.Deserialize>(data);try{//放入缓存中

HttpContext.Current.Cache.Insert("ticket", ticketMsg["ticket"], null, DateTime.Now.AddSeconds(7100), TimeSpan.Zero, CacheItemPriority.Normal, null);return ticketMsg["ticket"].ToString();

}catch(Exception ex)

{returnex.Message;

}

}///

///微信权限签名的 sha1 算法///签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同///

/// 获取到的jsapi_ticket

/// 生成签名的随机串

/// 生成签名的时间戳

/// 签名用的url必须是调用JS接口页面的完整URL

///

public string GetShal(string jsapi_ticket, string noncestr, long timestamp, stringurl)

{string strSha1 = string.Format("jsapi_ticket={0}&noncestr={1}&timestamp={2}&url={3}", jsapi_ticket, noncestr, timestamp, url);return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(strSha1, "sha1").ToLower();

}///

///微信权限签名( sha1 算法 )///签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同///

/// 第三方用户唯一凭证

/// /// 第三方用户唯一凭证密钥,即appsecret

/// 生成签名的随机串

/// 生成签名的时间戳

/// 签名用的url必须是调用JS接口页面的完整URL

///

public string Get_Signature(string AppId, string AppSecret, string noncestr, long timestamp, stringurl)

{string access_token = GetAccess_Token(AppId, AppSecret); //获取全局的access_token

string jsapi_ticket = GetJsapi_Ticket(access_token); //获取jsapi_ticket

string strSha1 = string.Format("jsapi_ticket={0}&noncestr={1}&timestamp={2}&url={3}", jsapi_ticket, noncestr, timestamp, url);return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(strSha1, "sha1").ToLower();

}///

///微信权限签名( sha1 算法 )///签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同///

/// 第三方用户唯一凭证

/// /// 第三方用户唯一凭证密钥,即appsecret

/// 生成签名的随机串

/// 生成签名的时间戳

/// 签名用的url必须是调用JS接口页面的完整URL

///

public void signatureOut(string AppId, string AppSecret, string noncestr, long timestamp, string url, out string access_token, out string jsapi_ticket, out stringsignature)

{

access_token= GetAccess_Token(AppId, AppSecret); //获取全局的access_token

jsapi_ticket= GetJsapi_Ticket(access_token); //获取jsapi_ticket

string strSha1 = string.Format("jsapi_ticket={0}&noncestr={1}&timestamp={2}&url={3}", jsapi_ticket, noncestr, timestamp, url);

signature= System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(strSha1, "sha1").ToLower();

}private string[] strs = new string[]

{"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};///

///创建随机字符串///

///

public stringCreatenNonce_str()

{

Random r= newRandom();var sb = newStringBuilder();var length =strs.Length;for (int i = 0; i < 15; i++)

{

sb.Append(strs[r.Next(length- 1)]);

}returnsb.ToString();

}///

///创建时间戳///

///

public longCreatenTimestamp()

{return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;

}

}

前段调用

var strUrl = location.href.split('#')[0];

$.ajax({

type:"Post",

url:"config.aspx/GetKey",//方法传参的写法一定要对,strUrl为形参的名字

data: "{'str':'" + strUrl + "'}",

contentType:"application/json; charset=utf-8",

dataType:"json",

success:function(data) {//返回的数据用data.d获取内容

$("#wx-share-sign").val(data.d.signature);

wxconifg(data.d);

},

error:function(err) {

alert('55');

}

});functionwxconifg(WXDate) {

wx.config({

debug:false,

appId:'你的APPID',

timestamp: WXDate.timestamp,

nonceStr: WXDate.nonceStr,

signature: WXDate.signature,

jsApiList: ["checkJsApi", "onMenuShareTimeline", "onMenuShareAppMessage", "onMenuShareQQ", "onMenuShareQZone"]

});

wx.ready(function() {

wx.onMenuShareAppMessage({

title: $("#wx-share-title").val(),

desc: $("#wx-share-desc").val(),

link: strUrl,

imgUrl: $("#wx-share-img").val(),

trigger:function(res) {

},

success:function(res) {

},

cancel:function(res) {

},

fail:function(res) {

alert(JSON.stringify(res));

}

});//分享到朋友圈

wx.onMenuShareTimeline({

title:'XX新闻|'+$("#wx-share-desc").val(),

desc: $("#wx-share-desc").val(),

link: $("#wx-share-link").val(),

imgUrl: $("#wx-share-img").val(),

type:'link',

dataUrl: strUrl,

trigger:function(res) {

},

success:function(res) {

},

cancel:function(res) {

},

fail:function(res) {

alert(JSON.stringify(res));

}

});

});

}

java 微信分享朋友圈 链接显示图片_【微信开发】-- 微信分享功能(分享到朋友和朋友圈显示图片和简介)...

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。