zoukankan      html  css  js  c++  java
  • 微信网页JS分享,微信二次分享无缩略图问题

    很多时候我们要在微信中分享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('#')[0];//动态获取当前地址,防止微信在原地址后加入参数
    
            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(1000, 9999) * 10000);
        $.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, "无效参数", 401);
                try
                {
                    string AppId = "xxxxxxxx";//微信公众号官网签发的 appid和appsecret
                    string AppSecret = "xxxxxxx";
                    DateTime endDate = DateTime.Now.AddSeconds(7200);
                    string token = "", ticket = "";
                    List<Models.WeiXinTokens> list = WeiXinTokensBLL.GetList();
                    if (list != null && list.Count > 0)
                    {
                        if (list[0].EndDate > DateTime.Now)
                        {
                            token = list[0].Token.Trim();
                            ticket = list[0].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 > 0)
                            {
                                wxt.ID = list[0].ID;
                                WeiXinTokensBLL.ModifyEntity(wxt);
                            }
                            else
                            {
                                WeiXinTokensBLL.Append(wxt);
                            }
    
                            token = model.token;
                            ticket = model.ticket;
                        }
                    }
                    else
                    {
                        Models.WeiXinTokens wxt = list[0];
                        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 = 200;
                    json.Data = jsonStr;
                }
                catch (Exception ex)
                {
                    json.Success = false;
                    json.Msg = "服务器无响应";
                    json.Code = 500;
                    json.Data = -1;
                }
    
                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(1970, 1, 1));
                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 == "0")
                {
                    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

  • 相关阅读:
    设计模式的分类
    SQL Server 2005 TSQL 学习笔记:排名函数
    JS正则表达式语法
    魅族 “拜产品教”公司的优秀与局限
    jqueryMobile初始化组件
    Loading Scripts Without Blocking
    LabJs学习笔记:分析图
    翻转的css3样式
    IE(IE6/IE7/IE8)支持HTML5标签
    我的空间轨迹!
  • 原文地址:https://www.cnblogs.com/xsj1989/p/7919921.html
Copyright © 2011-2022 走看看