很多时候我们要在微信中分享h5网页,这个时候就得用微信的分享接口来自定义分享的地址、标题、描述、缩略图了。

分享到微信的时候遇到一个问题,就是第一次分享到微信里,是正确的,但是在微信打开分享的链接,再次分享的时候,发现小图片没了。

原因就是微信在你分享的时候,会自动给你分享的地址后面加入参数,导致你分享的地址改变了,这时候再去用原来的地址获取签名,就不能用了。

解决方法,动态获取地址:

var link = encodeURIComponent(location.href.split('#')[0]);//编码动态获取地址

var link = location.href.split('#')[0];//动态获取地址

代码:

 <script src="js/jquery.min.js"></script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script src="js/sha1.js"></script>
<script src="js/WeiXinShare.js"></script>
<script type="text/javascript">
//var link = "http://adv.xxx.com/Index.html";//原网页地址
//var link = encodeURIComponent(location.href.split('#')[0]);//编码动态获取地址
//var link = "http://adv.xxx.com/Index.html?from=groupmessage";//微信加入参数后的地址
var link = location.href.split('#')[];//动态获取当前地址,防止微信在原地址后加入参数 var imgUrl = "http://adv.xxx.com/img/fm.png";//缩略图地址
var apiUrl = "https://api.xxx.com/Common/GetSignature";//服务器端签名
var title = "这里是分享标题";
var desc = "这里是分享描述";
Share(link, imgUrl, title, desc, apiUrl);
</script>

Share函数代码:

function Share(link, imgUrl, title, desc, apiUrl) {
var randNum = Math.floor(Math.random(, ) * );
$.ajax({
url: apiUrl,
type: 'GET',
dataType: 'jsonp',
async: false,
data:
{
linkUrl: link,
randNum: randNum
}
}).done(function (d) {
//debugger;
ShareCallBack(d, link, imgUrl, title, desc);
}).fail(function () {
console.log("error");
}).always(function () {
});
} function ShareCallBack(d, link, imgUrl, title, desc) {
//debugger;
var appid = "";
var timestamp = "";
var noncestr = "";
var signature = "";
if (d.Data != undefined && d.Data != null) { var result = $.parseJSON(d.Data);
timestamp = result.timestamp;
noncestr = result.noncestr;
signature = result.signature;
appid = result.appid; //weixin begin
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: appid, // 必填,公众号的唯一标识
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: noncestr, // 必填,生成签名的随机串
signature: signature, // 必填,签名,见附录1
jsApiList: ["onMenuShareTimeline", "onMenuShareAppMessage", "onMenuShareQQ", "onMenuShareWeibo", "onMenuShareQZone"]
//jsApiList 必填,需要使用的JS接口列表,所有JS接口列表见附录2
}); wx.ready(function () {
//获取“分享到朋友圈”按钮点击状态及自定义分享内容接口
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
wx.onMenuShareTimeline({
title: title, // 分享标题
desc: desc, // 分享描述
link: link, // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
}); //获取“分享给朋友”按钮点击状态及自定义分享内容接口
wx.onMenuShareAppMessage({
title: title, // 分享标题
desc: desc, // 分享描述
link: link, // 分享链接
imgUrl: imgUrl, // 分享图标
type: 'link', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
}); //获取“分享到QQ”按钮点击状态及自定义分享内容接口
wx.onMenuShareQQ({
title: title, // 分享标题
desc: desc, // 分享描述
link: link, // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
//获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口
wx.onMenuShareWeibo({
title: title, // 分享标题
desc: desc, // 分享描述
link: link, // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
//获取“分享到QQ空间”按钮点击状态及自定义分享内容接口
wx.onMenuShareQZone({
title: title, // 分享标题
desc: desc, // 分享描述
link: link, // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
}); wx.error(function (res) { // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
}); });
//weixin end
}
}

服务器端签名:

/// <summary>
/// 获取微信 signature
/// </summary>
/// <param name="callback"></param>
[AcceptVerbs("GET")]
public void GetSignature(string callback, string linkUrl)
{
MessagesDataCodeModel json = new MessagesDataCodeModel(false, "无效参数", );
try
{
string AppId = "xxxxxxxx";//微信公众号官网签发的 appid和appsecret
string AppSecret = "xxxxxxx";
DateTime endDate = DateTime.Now.AddSeconds();
string token = "", ticket = "";
List<Models.WeiXinTokens> list = WeiXinTokensBLL.GetList();
if (list != null && list.Count > )
{
if (list[].EndDate > DateTime.Now)
{
token = list[].Token.Trim();
ticket = list[].Ticket.Trim();
}
} if (string.IsNullOrEmpty(token))
{
string result = Common.WeiXinHelper.GetJsApiTicket(AppId, AppSecret);
JavaScriptSerializer jss = new JavaScriptSerializer();
WeiXinTokenModel model = jss.Deserialize<WeiXinTokenModel>(result);
if (model != null)
{
Models.WeiXinTokens wxt = new Models.WeiXinTokens();
wxt.Token = model.token;
wxt.Ticket = model.ticket;
wxt.EndDate = endDate;
if (list.Count > )
{
wxt.ID = list[].ID;
WeiXinTokensBLL.ModifyEntity(wxt);
}
else
{
WeiXinTokensBLL.Append(wxt);
} token = model.token;
ticket = model.ticket;
}
}
else
{
Models.WeiXinTokens wxt = list[];
wxt.Token = token;
wxt.Ticket = ticket;
WeiXinTokensBLL.ModifyEntity(wxt);
} string noncestr = Guid.NewGuid().ToString().Replace("-", "");
int timestamp = Utils.ConvertDateTimeInt(DateTime.Now);
string key_str = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + linkUrl;
string signature = Utils.EncryptToSHA1(key_str);
string jsonStr = "{\"ticket\":\"" + ticket + "\",\"token\":\"" + token + "\",\"noncestr\":\"" + noncestr + "\",\"timestamp\":\"" + timestamp + "\",\"appid\":\"" + AppId + "\",\"signature\":\"" + signature + "\",\"url\":\"" + linkUrl + "\"}";
json.Success = true;
json.Msg = "操作成功";
json.Code = ;
json.Data = jsonStr;
}
catch (Exception ex)
{
json.Success = false;
json.Msg = "服务器无响应";
json.Code = ;
json.Data = -;
} string str = ToJsonTran.ToJson2(json);
if (!string.IsNullOrEmpty(callback))
{
str = callback + "(" + str + ")";
}
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.Write(str);
System.Web.HttpContext.Current.Response.End();
}

辅助方法:

/// <summary>
/// C# SHA1散列算法
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string EncryptToSHA1(string str)
{
byte[] cleanBytes = Encoding.Default.GetBytes(str);
byte[] hashedBytes = System.Security.Cryptography.SHA1.Create().ComputeHash(cleanBytes);
return BitConverter.ToString(hashedBytes).Replace("-", "");
}
/// <summary>
/// DateTime时间格式转换为Unix时间戳格式
/// </summary>
/// <param name="time"> DateTime时间格式</param>
/// <returns>Unix时间戳格式</returns>
public static int ConvertDateTimeInt(System.DateTime time)
{
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(, , ));
return (int)(time - startTime).TotalSeconds;
}

签名程序:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization; namespace Common
{
public class WeiXinHelper
{
public static string GetJsApiTicket(string AppId, string AppSecret)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
string result_token = GetAccessToken(AppId, AppSecret);
string result_jsapi_ticket = "";
if (!string.IsNullOrEmpty(result_token))
{
result_jsapi_ticket = GetJsApiTicketByToken(result_token);
}
return "{\"token\":\"" + result_token + "\",\"ticket\":\"" + result_jsapi_ticket + "\"}";
} /// <summary>
/// 获得微信AccessToken
/// 正常返回:{"access_token":"ACCESS_TOKEN","expires_in":7200}
/// 错误返回:{"errcode":40013,"errmsg":"invalid appid"}
/// </summary>
/// <param name="AppId"></param>
/// <param name="AppSecret"></param>
/// <returns></returns>
public static string GetAccessToken(string AppId, string AppSecret)
{
string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + AppId + "&secret=" + AppSecret;
string result_token = "";
WebRequest webRequest = System.Net.HttpWebRequest.Create(url);
WebResponse webResponse = webRequest.GetResponse();
Stream stream = webResponse.GetResponseStream();
using (StreamReader sr = new StreamReader(stream))
{
result_token = sr.ReadToEnd();
} JavaScriptSerializer jss = new JavaScriptSerializer();
WeiXinAccessTokenResult atr = jss.Deserialize<WeiXinAccessTokenResult>(result_token);
if (!string.IsNullOrEmpty(atr.access_token))
{
return atr.access_token;
}
return "";
} public static string GetJsApiTicketByToken(string AccessToken)
{
string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + AccessToken + "&type=jsapi";
string result = Utils.ClientRequest(url, "", "GET");
JavaScriptSerializer jss = new JavaScriptSerializer();
WeiXinJsApiTicketResult ticket_model = jss.Deserialize<WeiXinJsApiTicketResult>(result);
if (ticket_model.errcode == "")
{
return ticket_model.ticket;
}
return "";
}
}
public class WeiXinJsApiTicketResult
{
public string errcode { get; set; }
public string errmsg { get; set; }
public string ticket { get; set; }
public string expires_in { get; set; }
}
public class WeiXinAccessTokenResult
{
//正常返回:{"access_token":"ACCESS_TOKEN","expires_in":7200}
//错误返回:{"errcode":40013,"errmsg":"invalid appid"}
public string access_token { get; set; }
public string expires_in { get; set; }
public string errcode { get; set; }
public string errmsg { get; set; }
public string error { get; set; }
}
}

微信分享SDK:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

微信网页JS分享,微信二次分享无缩略图问题的更多相关文章

  1. VueJs单页应用实现微信网页授权及微信分享功能

    在实际开发中,无论是做PC端.WebApp端还是微信公众号等类型的项目的时候,或多或少都会涉及到微信相关的开发,最近公司项目要求实现微信网页授权,并获取微信用户基本信息的功能及微信分享的功能,现在总算 ...

  2. 手把手实现微信网页授权和微信支付,附源代码(VUE and thinkPHP)

    wechat github 手把手实现微信网页授权和微信支付,附源代码(VUE and thinkPHP) 概述 公众号开发是痛苦的,痛苦在好多问题开发者文档是没有提到的,是需要你猜的. 在开发过程中 ...

  3. 微信公众号jssdk自定义分享,二次分享自定义失败解决技巧

    百度上自定义微信分享标题以及描述的解决方法有很多,基本上都能实现一次分享:流程基本上是这样的 1.首先引入微信jssdk =><script src="http://res.wx ...

  4. 微信网页开发调用微信jssdk接口遇到的坑以及最终解决方法 (持续更新)

    1.微信网页开发调用jssdk时报permission denied 大致是两个原因 (1)首先注册时未将你所调用的接口名字添加至jsApiList (2)第二个就是你的这个公众号没有权限使用这个ap ...

  5. h5聊天室web端(仿微博、微信)|h5仿微信网页端|仿微信界面弹窗

    这段时间一直在着手h5开发手机端聊天系统——html5仿微信聊天室,最近又在原先基础上开发了一个仿微信.微博网页web版聊天系统,使用到了HTML5+css3+jQuery+wcpop等技术开发,弹窗 ...

  6. 微信、qq二次分享

    前言 我们平时做微信分享的时候,一般分享出来的页面都是一个简单的html页面,不会加入框架之类的东西.所以当我们在分享出来的页面里面再次进行分享的时候,由于我们没有配置分享的标题.描述这些东西,分享出 ...

  7. 服务号使用微信网页授权(H5应用等)

    获取授权准备 AppId 服务号已经认证且获取到响应接口权限 设置网页授权域名 公众号设置 - 功能设置 - 网页授权域名.注意事项: 回调页面域名或路径需使用字母.数字及"-"的 ...

  8. [微信小程序] 认识微信小程序及开发环境搭建

    微信公众平台首页 https://mp.weixin.qq.com 微信公众平台测试帐号系统 https://open.weixin.qq.com/connect/qrconnect?appid=wx ...

  9. 微信、qq网页二次分享

    二次分享是指,在APP或者浏览器分享到微信或者qq,然后从微信或者qq再分享到别的平台.如果不处理,再次分享出去的图片或者标题就不会显示,对用户非常不友好. 一.微信二次分享 官方接入文档:https ...

随机推荐

  1. How to Pronounce AR, ORN, etc.

    How to Pronounce AR, ORN, etc. Share Tweet Share The R consonant can be really tricky.  In this vide ...

  2. How to Pronounce the Idiom: ‘Out Like a Light’

    How to Pronounce the Idiom: ‘Out Like a Light’ Share Tweet Share Tagged With: Idioms English is full ...

  3. ArcGIS Python编程案例-电子资料链接

    ArcGIS Python编程案例(1)-Python语言基础 https://www.jianshu.com/p/dd90816d019b ArcGIS Python编程案例(2)-使用ArcPy编 ...

  4. MVC模式浅谈

    MVC模式浅谈 一.MVC模式概述 模型-视图-控制器(MVC模式)是一种非常经典的软件架构模式,在UI框架和UI设计思路中扮演着非常重要的角色.从设计模式的角度来看,MVC模式是 一种复合模式,它将 ...

  5. js高级-原型链

    JavaScript是基于原型的面向对象的语言(相当于一个基类,父类),而不是像Java通过类模板构造实例,通过原型实现属性函数的复用 函数都有 prototype属性 指向函数的原型对象 只有函数根 ...

  6. apache常见的一些配置

    <VirtualHost *:80>ServerName www.aliyun.com #域名ServerAlias www.aliyun.com #别名DocumentRoot /dat ...

  7. 立个FLAG

    今天再次初步浏览了寒假生活: 三篇阅读笔记(人月神话,梦断代码,程序员修炼之道:从小工到专家),2月24日之前发表开发记账本软件,连续七天以上发表开发进度 学会使用GitHub,录制抖音(父母评价作品 ...

  8. k8s 调度器

    https://blog.csdn.net/qq_21816375/article/details/78209605

  9. CSS 美化radio checkbox

    CSS 样式 <style type="text/css"> .option-input { -webkit-appearance: none; -moz-appear ...

  10. mysql创建用户和库

    先用root登陆mysql,然后运行下面代码创建mysql用户和库 下面创建的帐号:test123  密码:123456  库名:test123 CREATE USER '; GRANT USAGE ...