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

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

    官方文档在这里,https://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html

    参考 http://www.cnblogs.com/stoneniqiu/p/6286599.html 这篇文章。

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

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

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

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

     

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

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

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

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

     二、前端配置

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

    <script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"></script>

    根据官方的配置参数,我们可以定义一个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: 'http://www.warmwood.com/home/lampindex', // 分享链接
                imgUrl: 'http://www.warmwood.com/images/s1.jpg',
                success: function (res) {
                    alert('已分享');
                },
                cancel: function (res) {
                    alert('已取消');
                },
                fail: function (res) {
                    alert(JSON.stringify(res));
                }
            });
            //朋友
            wx.onMenuShareAppMessage({
                title: '暖木科技', // 分享标题
                desc: '宝宝的睡眠很重要,你的睡眠也很重要', // 分享描述
                link: 'http://www.warmwood.com/home/lampindex', // 分享链接
                imgUrl: 'http://www.warmwood.com/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.weixin.qq.com/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<TokenResult>(null, url, null, CommonJsonSendType.GET);
                return res;
            }
    复制代码
    复制代码

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

    2.获取jsapi_ticket

    access_token的作用就是为了获取jsapi_ticket。用get方式获取,url:https://api.weixin.qq.com/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<jsapiTicketModel>(accessToken, url, "", CommonJsonSendType.GET);
            }

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

     private void setCacheTicket(string cache)
            {
                _cacheManager.Set(tokenKey, cache, 7200);
            }

    MemoryCacheManager:

    View Code

    3.签名

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

    么有C#的demo,支付那边都提供了,为啥jssdk没有提供,好吧先不吐槽了。官方也说明白签名的规则。一开始我使用的是https://github.com/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 = sha1.ComputeHash(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 = sha1.ComputeHash(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 = "http://www.warmwood.com/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。

    参考资料:

    签名校验:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign

    官方文档:https://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html

     

    我的核心代码

    复制代码
    [System.Web.Services.WebMethod]
        public static WXShareModel GetKey(string str)
        {
            WXShareModel aModel = new WXShareModel();
            WXToolsHelper tb = new WXToolsHelper();
            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();
            return aModel;
        }
    public class WXShareModel
        {
            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 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 = Sha1(string1, Encoding.Default);
            }
     public static string Sha1(string orgStr, Encoding encode)
            {
                SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
                byte[] bytes_in = encode.GetBytes(orgStr);
                byte[] bytes_out = sha1.ComputeHash(bytes_in);
                sha1.Dispose();
                string result = BitConverter.ToString(bytes_out);
                result = result.Replace("-", "");
                return result;
            }
    public class WXToolsHelper
        {
            /// <summary>
            /// 获取全局的access_token,程序缓存
            /// </summary>
            /// <param name="AppId">第三方用户唯一凭证</param>
            /// <param name="AppSecret">第三方用户唯一凭证密钥,即appsecret</param>
            /// <returns>得到的全局access_token</returns>
            public string GetAccess_Token(string AppId, string AppSecret)
            {
                try
                {
                    //先查缓存数据
                    if (HttpContext.Current.Cache["access_token"] != null)
                    {
                        return HttpContext.Current.Cache["access_token"].ToString();
                    }
                    else
                    {
                        return GetToken(AppId, AppSecret);
                    }
                }
                catch
                {
                    return GetToken(AppId, AppSecret);
                }
            }
    
            /// <summary>
            /// 获取全局的access_token
            /// </summary>
            /// <param name="AppId">第三方用户唯一凭证</param>
            /// <param name="AppSecret">第三方用户唯一凭证密钥,即appsecret</param>
            /// <returns>得到的全局access_token</returns>
            public string GetToken(string AppId, string AppSecret)
            {
                var client = new System.Net.WebClient();
                client.Encoding = System.Text.Encoding.UTF8;
                var url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", AppId, AppSecret);
                var data = client.DownloadString(url);
                var jss = new JavaScriptSerializer();
                var access_tokenMsg = jss.Deserialize<Dictionary<string, object>>(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();
            }
    
    
            /// <summary>
            /// 获取jsapi_ticket,程序缓存
            /// </summary>
            /// <param name="access_token">全局的access_token</param>
            /// <returns>得到的jsapi_ticket</returns>
            public string GetJsapi_Ticket(string access_token)
            {
                try
                {
                    //先查缓存数据
                    if (HttpContext.Current.Cache["ticket"] != null)
                    {
                        return HttpContext.Current.Cache["ticket"].ToString();
                    }
                    else
                    {
                        return GetTicket(access_token);
                    }
                }
                catch
                {
                    return GetTicket(access_token);
                }
            }
    
    
            /// <summary>
            /// 获取jsapi_ticket
            /// </summary>
            /// <param name="access_token">全局的access_token</param>
            /// <returns>得到的jsapi_ticket</returns>
            public string GetTicket(string access_token)
            {
                var client = new System.Net.WebClient();
                client.Encoding = System.Text.Encoding.UTF8;
                var url = string.Format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi", access_token);
                var data = client.DownloadString(url);
                var jss = new JavaScriptSerializer();
                var ticketMsg = jss.Deserialize<Dictionary<string, object>>(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)
                {
                    return ex.Message;
                }
            }
    
            /// <summary>
            /// 微信权限签名的 sha1 算法
            /// 签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同
            /// </summary>
            /// <param name="jsapi_ticket">获取到的jsapi_ticket</param>
            /// <param name="noncestr">生成签名的随机串</param>
            /// <param name="timestamp">生成签名的时间戳</param>
            /// <param name="url">签名用的url必须是调用JS接口页面的完整URL</param>
            /// <returns></returns>
            public string GetShal(string jsapi_ticket, string noncestr, long timestamp, string url)
            {
                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();
            }
    
            /// <summary>
            /// 微信权限签名( sha1 算法 )
            /// 签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同
            /// </summary>
            /// <param name="AppId">第三方用户唯一凭证</param>
            /// /// <param name="AppSecret">第三方用户唯一凭证密钥,即appsecret</param>
            /// <param name="noncestr">生成签名的随机串</param>
            /// <param name="timestamp">生成签名的时间戳</param>
            /// <param name="url">签名用的url必须是调用JS接口页面的完整URL</param>
            /// <returns></returns>
            public string Get_Signature(string AppId, string AppSecret, string noncestr, long timestamp, string url)
            {
                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();
            }
    
    
            /// <summary>
            /// 微信权限签名( sha1 算法 )
            /// 签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同
            /// </summary>
            /// <param name="AppId">第三方用户唯一凭证</param>
            /// /// <param name="AppSecret">第三方用户唯一凭证密钥,即appsecret</param>
            /// <param name="noncestr">生成签名的随机串</param>
            /// <param name="timestamp">生成签名的时间戳</param>
            /// <param name="url">签名用的url必须是调用JS接口页面的完整URL</param>
            /// <returns></returns>
            public void signatureOut(string AppId, string AppSecret, string noncestr, long timestamp, string url, out string access_token, out string jsapi_ticket, out string signature)
            {
                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"
    };
            /// <summary>
            /// 创建随机字符串 
            /// </summary>
            /// <returns></returns>
            public string CreatenNonce_str()
            {
                Random r = new Random();
                var sb = new StringBuilder();
                var length = strs.Length;
                for (int i = 0; i < 15; i++)
                {
                    sb.Append(strs[r.Next(length - 1)]);
                }
                return sb.ToString();
            }
    
    
            /// <summary>
            /// 创建时间戳 
            /// </summary>
            /// <returns></returns>
            public long CreatenTimestamp()
            {
                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');
        }
    });
    function wxconifg(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));
                }
            });
        });
    } 
    复制代码
    展开全文
  • 微信分享完整demo

    2020-07-30 23:30:05
    微信分享完整demo,带appid,同时有签名文件,下载可用
  • 微信分享链接的缩略图和标题

    万次阅读 2019-12-11 09:24:03
    一、微信分享微信内打开链接后,点右上角【…】选择【发送给朋友】或【分享到朋友圈】,这种分享方式获取缩略图的方法: 方法一:在页面 body 最上方添加 300*300 像素的 img 如该图片不需要显示,可以用 css ...

    一、微信内分享


    在微信内打开链接后,点右上角【…】选择【发送给朋友】或【分享到朋友圈】,这种分享方式获取缩略图的方法:

    • 方法一:在页面 body 最上方添加 300*300 像素的 img

    如该图片不需要显示,可以用 css 隐藏,但不能直接对 img 设置 display: none;

    可以在父层 div 上设置 display: none; 或者对 img 设置 position: absolute; visibility: hidden;

    <div style="display:none;"><img src="/img/thumbnail.png" alt=""></div>
    
    • 方法二:通过微信 JS-SDK 的分享接口

    这种方法需要一个微信公众号的 app_id,同时需要一个后端服务生成 signature。好处是可以定制分享的标题、缩略图、描述。

    二、从浏览器分享


    在浏览器打开链接后,点分享图标,选择【微信】,这种分享方式获取缩略图的方法:

    在页面的 head 部分添加 Open Graph Metadata

    <meta property="og:type" content="website" />
    <meta property="og:title" content="页面标题">
    <meta property="og:description" content="页面描述">
    <meta property="og:image" content="http://www.example.com/img/thumbnail.png">
    <meta property="og:url" content="http://www.example.com/">
    

    其中 og:image 影响浏览器分享时的图标,需要指定图片的完整路径。

    https://github.com/thedaviddias/Front-End-Checklist

    展开全文
  • H5微信分享、自定义微信分享

    万次阅读 热门讨论 2019-08-12 08:54:09
    在微信公众平台的接口权限内可以看到,个人版公众号是没有权限自定义微信分享的,所以需要企业版公众号并开通认证。 具体步骤: 步骤一:绑定域名 先登录微信公众平台进入“公众号设置”的“功能设置”里...

    在一个h5页面添加微信,分享给微信好友、朋友圈、腾讯微博

    下面来实现 。

    需要:

    1、需要一个企业版的微信公众号(认证过的)

    2、一台服务器

    企业版的微信公众号原因:

    在微信公众平台的接口权限内可以看到,个人版公众号是没有权限自定义微信分享的,所以需要企业版公众号并开通认证。

    具体步骤:

    步骤一:绑定域名

    先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。

    备注:登录后可在“开发者中心”查看对应的接口权限。(这一步骤应该没有什么问题)

    步骤二:引入JS文件

    在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.4.0.js

    如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.4.0.js (支持https)。

    备注:支持使用 AMD/CMD 标准模块加载方法加载(没问题,很简单,一个script就搞定了)

    步骤三:通过config接口注入权限验证配置

    所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。

    wx.config({
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: '', // 必填,公众号的唯一标识
        timestamp: , // 必填,生成签名的时间戳
        nonceStr: '', // 必填,生成签名的随机串
        signature: '',// 必填,签名
        jsApiList: [] // 必填,需要使用的JS接口列表
    });

    这一步就有很大的问题了,这么多的参数是从哪里来的!

    ——1.先不管其他的,我们现在所需要的:(appId是微信公众号的appId,可以写死或者服务器返回)

      timestamp: , // 必填,生成签名的时间戳
        nonceStr: '', // 必填,生成签名的随机串
        signature: '',// 必填,签名

    这样看来,其实真正需要的是 signature 签名

    ——2.看下signature 的生成流程:

    生成签名之前必须先了解一下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

    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

    上面的是官方的文档,说要拿到并且缓存 access_token 接口调用凭据 和 jsapi_ticket 临时票据,拿着access_token 去获取jsapi_ticket ,获得jsapi_ticket之后,自己生成个随机字符串(不懂的,网上百度怎么搞)加上时间戳,加上url地址,自己拼接好,最后进行sha1处理,就得到signature, 很是扯皮!另外access_token 一天的次数2000次jsapi_ticket 一天的次数是100万次,都缓存下来,也可以只缓存token;(我是只缓存了token)

    ——这里说一下 access_token 

    access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

    公众平台的API调用所需的access_token的使用及生成方式说明:

    1、建议公众号开发者使用中控服务器统一获取和刷新Access_token,其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务;

    2、目前Access_token的有效期通过返回的expire_in来传达,目前是7200秒之内的值。中控服务器需要根据这个有效时间提前去刷新新access_token。在刷新过程中,中控服务器可对外继续输出的老access_token,此时公众平台后台会保证在5分钟内,新老access_token都可用,这保证了第三方业务的平滑过渡;

    3、Access_token的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新access_token的接口,这样便于业务服务器在API调用获知access_token已超时的情况下,可以触发access_token的刷新流程。

    公众号和小程序均可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在“微信公众平台-开发-基本配置”页中获得(需要已经成为开发者,且帐号没有异常状态)。调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,点击查看设置方法,否则将无法调用成功。小程序无需配置IP白名单。

    简单来说就是调用微信的分享接口,需要用到一个凭证access_token,而这个凭证是有数量和有效时间限制的,所以需要用自己的服务器做缓存处理,当access_token过期后再去请求新的access_token,需要一台服务器和配置ip白名单。

    PHP来做的话:

     a. 先定义个access_tokenjson文件,我选择用json文件存,没有用数据库存

    {
        "access_token": "xxx",
        "expires": 12345
    }

     b.jssdk.php文件: 文件夹目录要有修改权限 sudo chmod -R 777 your_dir 

    思路:先取缓存的token的时间,与现在的时间对比,如果现在的时间大于缓存时间,则把现在时间+7200赋给缓存的时间,如果超时请求新的token,如果没超时用缓存的token,再生成jsapi_ticket,生成signature签名。

    步骤四:通过ready接口处理成功验证 又回到前端页面上

    wx.ready(function(){
        // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
    });

    配置好就可以用分享接口了

    分享接口

    自定义“分享给朋友”及“分享到QQ”按钮的分享内容(1.4.0)

     

    wx.ready(function () {   //需在用户可能点击分享按钮前就先调用
        wx.updateAppMessageShareData({ 
            title: '', // 分享标题
            desc: '', // 分享描述
            link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
            imgUrl: '', // 分享图标
            success: function () {
              // 设置成功
            }
    });

    更多接口可以去文档里看

     

    展开全文
  • 微信分享功能

    万次阅读 2018-07-30 18:06:05
    最近在做手机端页面,需要一个分享功能,其实自身分享是可以的,但是为了分享出的内容丰富,比如缩略图了,描述了等等,如下图所示: 步骤一:绑定域名 先登录微信公众平台进入“公众号设置”的“功能设置”里...

    最近在做手机端页面,需要一个分享功能,其实自身分享是可以的,但是为了分享出的内容丰富,比如缩略图了,描述了等等,如下图所示:
    这里写图片描述

    步骤一:绑定域名
    先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
    备注:登录后可在“开发者中心”查看对应的接口权限。

    步骤二:引入JS文件
    在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js
    首先查看下官方文档,通过查看微信公众平台文档,找到需要的说明文档,明确开发步骤,说明文档截图如下
    这里写图片描述
    在微信JS-SDK说明文档中找到 分享接口

    获得Access Token 和 jsapi_ticket这些需要后台去做

    1. 获得Access Token
      首先,登录公众号平台->基本配置:
      这里写图片描述
      然后,获取access_tonken:
      获取方式说明:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183
      access_tonken有效期7200秒,开发者必须在自己的服务全局缓存access_token我们只需要了解一下就可以,不需要我们缓存它;
    {"access_token":"ACCESS_TOKEN","expires_in":7200}

    成功返回如下JSON:
    2. 获取jsapi_ticket
    https请求方式: GET
    https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

    这里只有access_token是我们上一步获取的,type=jsapi按原样拼接;这时我们会拿到jsapi_ticket

    有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket我们只需要了解一下就可以,不需要我们缓存它;

    成功返回如下JSON:

    {
    "errcode":0,
    "errmsg":"ok",
    "ticket":"bxLdikRXVbTP5u5sUoXNKd8-41ZO3MhKoyN5OfkWITA",
    "expires_in":7200
    }

    获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。
    3. 第三个signature:
    出于安全考虑,开发者必须在服务器端实现签名的逻辑

    后台会返回 timestamp,noncestr,signature,appid,url
    根据后台返回的这些数据进行
    微信 JS 接口签名校验工具https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign

    前端代码 js

    // 微信分享默认调用接口
    var $appid,$timestamp,$noncestr,$signature,$description,$title1;
    //获取当前页面的url
    var linkUrl = window.location.href;
    //encodeURIComponent(),请求后台接口需要用encodeURIComponent()
    var encodeUrl = encodeURIComponent(linkUrl); 
    $.ajax({
        type : "GET",
        url : "这里写你调用的后台接口"+"?url=" + encodeUrl,
        cache : false,
        async : false,
        success : function(msg) {
            var data = JSON.parse(msg);
            console.log(data);
            if(data.code == 200){
                $appid = data.data.appid;  // appid
                $timestamp = data.data.timestamp;   // timestamp
                $noncestr = data.data.noncestr; // noncestr
                $signature = data.data.signature;  // signature
    
                var description = $("meta[name='description']").attr("content");
                if ($.trim(description) != "") {
                    $description = $.trim(description); // share_desc
                }
                var title1 = document.title;
                if ($.trim(title1) != "") {
                    $title1 = title1;// share_title
                }
    
                //**配置微信信息**
                wx.config ({
                    debug : false,
                    appId : $appid,
                    timestamp : $timestamp,
                    nonceStr : $noncestr,
                    signature : $signature,
                    jsApiList : [
                        // 所有要调用的 API 都要加到这个列表中
                        'onMenuShareTimeline',
                        'onMenuShareAppMessage',
                        'onMenuShareQQ',
                        'onMenuShareWeibo',
                        'onMenuShareQZone'
                    ]
                });
                wx.ready (function () {
                    // 微信分享的数据
                    var shareData = {
                        "imgUrl" : "",
                        "link" : linkUrl,
                        "desc" : $description,
                        "title" : $title1,
                        success : function () {
                            // 分享成功可以做相应的数据处理
                        }
                    };
                    //分享微信朋友圈
                    wx.onMenuShareTimeline (shareData);
                    //分享给朋友
                    wx.onMenuShareAppMessage({
                        title: $title1, // 分享标题
                        desc: $description, // 分享描述
                        link: linkUrl, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                        imgUrl: "", // 分享图标
                        type: '', // 分享类型,music、video或link,不填默认为link
                        dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
                        success: function () {
                            // 用户点击了分享后执行的回调函数
                        }
                    });
                    //分享到qq
                    wx.onMenuShareQQ (shareData);
                    //分享到微博
                    wx.onMenuShareWeibo (shareData);
                    //分享到qq空间
                    wx.onMenuShareQZone(shareData);
                });
    
    
    
            }
    
        },
        error : function(msg){
    
        }
    });
    

    这里需要注意的是:
    1.签名用的noncestrtimestamp必须与wx.config中的nonceStr和timestamp相同
    2.签名用的url必须是调用JS接口页面的完整URL。
    3.出于安全考虑,开发者必须在服务器端实现签名的逻辑
    如出现invalid signature 等错误详见附录5常见错误及解决办法

    展开全文
  • 关于H5页面在微信端的分享

    万次阅读 2018-09-10 15:38:24
    微信分享,咋一看好像很复杂,实则非常简单。只需要调用微信官方出的微信jssdk,加上些许配置,就可以实现h5页面在微信上的分享,官方文档地址为: https://mp.weixin.qq.com/wiki?t=resource/res_main&amp;id=...
  • 微信JSSDK分享功能详解

    万次阅读 热门讨论 2017-04-19 16:23:09
    微信6.0之后JSSDK的调用,微信分享功能的实现,傻瓜教程
  • 微信分享问题汇总

    2018-08-30 13:43:11
    最近开发微信活动的时候,发现分享到朋友圈和发送给朋友功能不稳定,时而有效时而无效,打开debug模式查看,发现多数报的数签名错误,仔细看了官方文档,最终问题出在ticket的缓存上。 1、签名: url: 需要根据...
  • 微信实现自定义分享功能

    千次阅读 2018-07-20 17:01:27
    今天小编写微信分享接口。上网查了下,代码很多,但都不是很全!所以,小编特地真理了下..... 0、效果 1、有一个认证过的微信公众号。 2、把你要分享的网站IP地址加入微信白名单。  需要把网站域名加入js...
  • 微信分享取消分享之后的回调仍是分享成功

    万次阅读 热门讨论 2018-09-17 14:20:46
    用的友盟SDK实现微信分享,发现微信分享途中如果取消分享,回调的error是nil,微信分享成功的回调返回的error也是nil,无法识别是否分享成功。问了友盟的客服才知道微信在8月13号对分享功能做了调整。...
  • 微信自定义分享,在pc客户端可以正常分享自定义的内容,但是手机客户端分享出去的内容却不是自定义分享的内容?不知道有哪位遇到过,谢谢
  • 微信自定义分享在pc正常手机端不正常问题

    千次阅读 热门讨论 2017-07-08 12:56:03
    微信自定义分享在pc正常手机端不正常问题
  • http://www.jiathis.com/ 打开以上网页,将代码复制到你的页面中,即可 优点:使用方便 缺点:无法做统计
  • 微信分享页面到朋友圈或者发送给朋友的时候,会把网址所带参数截断, 例如在微信里面打开:http://nrnc.net/52441/?a=12321 分享给朋友后,地址会变成: ... ... 这样的有什么解决方案??
  • 微信中,朋友圈互相分享好的文章已被大家所习惯和接受。自从用了企业号之后,就一直有这样的困扰——如何把好的文章分享到企业号中呢?经过近期对微信企业号开发的初步研究,发现可以在开通开发模式后,设置允许转发...
  • php 中去除中文的换行,str_replace(PHP_EOL,'',($res['share_content']));
  • http://www.paigu.com/column/a10.html 朋友圈 from=timeline&isappinstalled=0 微信微信群  from=groupmessage&isappinstalled=0 好友分享 from=singlemessage&isappinstalled=0
  • 如果你发现你其他操作没错,签名和微信开放平台的也一致,但是却报了微信应用签名与开放平台不一致的错误。 !!! 那你就要注意了:微信使用的应用签名必须是MD5,不能使用SHA1 ...
  • iOS 调起微信支付页面后,点击取消或支付成功无法返回原APP问题(不管是支付还是其他,都是返回应用的问题。) 是xcode里面的url没有设置好,这个url应该是在微信公共平台(open.weixin)里面的对应开发者自己...
  • 不要用百度分享分享工具,这样做的目的是为了能自定义分享按钮的样式。类似于36kr 的分享微信的功能,点击按钮,弹出该文章的二维码。 研究了蛮久,没懂 求高人指教!
1 2 3 4 5 ... 20
收藏数 199,916
精华内容 79,966
关键字:

微信分享