相信大家在做微信分享功能的时候一定会遇到很多奇怪的问题,有时候会出现一些无厘头的问题,自己明明都配置没问题了,却分享失败,下面给大家介绍一下微信分享经常出现的一些问题和出现问题的原因;
1、接口验证失败,详细信息:....
这是最常见的接口验证失败的问题,出现这种情况是因为微信验证签名失败的原因,这里又得说一下签名是如何生成的以及微信端是如何进行验签的。
string nonceStr = CreateNoncestr();
ViewBag.NonceStr = nonceStr;
string timeStamp = GetTimeStamp();
ViewBag.TimeStamp = timeStamp;
ViewBag.WechatUrl = Request.Url.ToString().Replace(":" + Request.Url.Port, null);
string jsapiTicket = GetJsapiTicket();
Dictionary<string, string> signData = new Dictionary<string, string>() {
{"noncestr",nonceStr},
{"jsapi_ticket",jsapiTicket},
{"timestamp",timeStamp},
{"url",Request.Url.ToString().Replace(":" + Request.Url.Port, null)}
};
ViewBag.Signature = WeChatHandler.Sign(signData);
生成签名必须的几个参数;nonceStr 随机字符串、timeStamp 时间戳、jsapiTicket (微信接口获取)、url 当前页面地址
代码贴出来咯:
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;
}
/// <summary>
/// 获取时间戳
/// </summary>
/// <returns></returns>
public static string GetTimeStamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
private static string getJsapiTicket()
{
string interfaceUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + AccessToken + "&type=jsapi";
HttpWebRequest webrequest = (HttpWebRequest)System.Net.HttpWebRequest.Create(interfaceUrl);
HttpWebResponse webresponse = (HttpWebResponse)webrequest.GetResponse();//请求连接,并反回数据
Stream stream = webresponse.GetResponseStream();//把返回数据转换成流文件
byte[] rsByte = new Byte[webresponse.ContentLength]; //把流文件转换为字节数组
try
{
stream.Read(rsByte, 0, (int)webresponse.ContentLength);
string strb = System.Text.Encoding.Default.GetString(rsByte, 0, rsByte.Length).ToString().Replace("{", "").Replace("}", "");
if ((strb.ToString().IndexOf("\"errcode\":42001") != -1) || (strb.ToString().IndexOf("\"errcode\":40001") != -1) || (strb.ToString().IndexOf("\"errcode\":40014") != -1) || (strb.ToString().IndexOf("\"errcode\":41001") != -1)) //access_token错误
{
if (repeatCount <= 3)
{
repeatCount++;
getAccessToken();
return getJsapiTicket();
}
else
{
return "error";
}
}
else if (strb.ToString().IndexOf("\"errcode\":0,\"errmsg\":\"ok\"") != -1)
{
string[] jsons = strb.Split(',');
if (jsons.Length == 4)
{
string[] param = jsons[2].Split(':');
if (param.Length == 2 && param[0] == "\"ticket\"")
{
string tempLastTime = DateTime.Now.ToString();
string tempJsapiTicket = param[1].Replace("\"", "");
return param[1].Replace("\"", "");
}
else
{
return "error";
}
}
return "error";
}
else
{
return "error";
}
}
catch (Exception exp)
{
return "error";
}
}
生成签名:
/// <summary>
/// 生成签名
/// </summary>
/// <param name="data">参与签名的参数字典</param>
/// <returns>签名</returns>
public static string Sign(Dictionary<string, string> data)
{
var dataList = data.ToList();
dataList.Sort(ParameterKeyComparison);
var queryString = dataList.Aggregate(string.Empty, (query, item) => string.Concat(query, "&", item.Key, "=", item.Value)).TrimStart('&');
using (var sha1 = new SHA1CryptoServiceProvider())
{
var hashed = sha1.ComputeHash(Encoding.Default.GetBytes(queryString));
return HexStringFromBytes(hashed);
}
}
private static string HexStringFromBytes(byte[] bytes)
{
var sb = new StringBuilder();
foreach (byte b in bytes)
{
var hex = b.ToString("x2");
sb.Append(hex);
}
return sb.ToString();
}
private static int ParameterKeyComparison(KeyValuePair<string, string> x, KeyValuePair<string, string> y)
{
return x.Key.CompareTo(y.Key);
}
前端初始化微信分享;
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: '@ViewBag.TimeStamp', // 必填,生成签名的时间戳
nonceStr: '@ViewBag.NonceStr', // 必填,生成签名的随机串
signature: '@ViewBag.Signature', // 必填,签名,见附录1
jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline', 'hideMenuItems'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
wx.ready(function () {
wx.onMenuShareAppMessage({
title: '@ViewBag.WebTitle',//分享标题
desc: '@ViewBag.WebDes',//说明
link: '@ViewBag.WechatUrl',//链接
imgUrl: '@ViewBag.ShareImg',//图片地址
trigger: function (res) {
},
success: function (res) {
if ($("#hdnId").val() == 18 && $("#hdnState").val() == 1) {
getSharePacket()
} else if ($("#hdnId").val() == 18 && $("#dhsourceId").val() == "203331" && $("#hdnWeChat").val() == "1") {
getSharePacket();
}
},
cancel: function (res) {
},
fail: function (res) {
alert(JSON.stringify(res));
//console.log(JSON.stringify(res));
}
});
wx.onMenuShareTimeline({
title: '@ViewBag.WebTitle',
desc: '@ViewBag.WebDes',
link: '@ViewBag.WechatUrl',
imgUrl: '@ViewBag.ShareImg',
trigger: function (res) {
},
success: function (res) {
if ($("#hdnId").val() == 18 && $("#hdnState").val() == 1) {
getSharePacket();
} else if ($("#hdnId").val() == 18 && $("#dhsourceId").val() == "203331" && $("#hdnWeChat").val() == "1") {
getSharePacket();
}
},
cancel: function (res) {
},
fail: function (res) {
alert(JSON.stringify(res));
//console.log(JSON.stringify(res));
}
});
wx.hideMenuItems({
menuList: ["menuItem:share:qq", "menuItem:share:weiboApp", "menuItem:favorite", "menuItem:share:facebook", "menuItem:share:QZone", "menuItem:openWithQQBrowser", "menuItem:openWithSafari", "menuItem:share:email"] // 要隐藏的菜单项,只能隐藏“传播类”和“保护类”按钮,所有menu项见附录3
});
});
wx.error(function (res) {
alert("接口验证失败,详细信息:\n" + JSON.stringify(res));
});
这里不就不介绍啦,相信大家都知道,别忘了引用 https://res.wx.qq.com/open/js/jweixin-1.0.0.js 哦
到这里就算配置完成啦,然后运行,如果出现了接口验证失败的问题,那可能是;
appId不正确;
获取的jsapiTicket不正确,导致生成的签名不正确;
url地址错误,导致生成的签名不正确;
页面js配置的timestamp、nonceStr和生成签名的timestamp、nonceStr不一致,导致验签失败;
2、如果上面的都正确,也不会弹出接口验证失败的信息,但是分享的时候就是没配置成功,那可能是因为:
页面分享链接域名没有在微信开发者平台配置;
微信开发者平台配置已经配置了域名,但还是分享失败,检查一下分享链接是http还是https,一般微信端页面为http分享链接为https也会出现分享不成功的情况,相反微信端是https分享链接是http也不行;