• 手机web如何实现多平台分享


      话说App一般都带有分享到社交平台的入口,web网页的分享也有很不错的框架,但是随着HTML5的不断发展,手机web页面越来越多的进入到我们的生活中,那如何在我们的手机上完成分享呢?话说各大分享平台都有针对Android、Ios的SDK,作为开发者,我们只需要将SDK集成的我们的项目中即可,通过提供的外部接口,我们可以很容易的完成分享的功能;web网页呢,网上也存在很多优秀的分享框架,例如:bShare分享 、JiaThis分享;我们可以很方便的集成到我们的项目中;但是手机web页面实现分享就需要我们下点功夫了,以为这个时候,我们就可以通过调用用户安装的客户端进行分享,这里需要特别提到的就是微信分享了,网页端我们分享时,一般都是弹出一个分享的二维码,我们使用微信App扫描然后进行分享,手机端我们就不能这样操作了,我们需要当用户选中微信分享时,直接打开App进行分享,这里就要吐槽一下微信的分享JS SDK了,初次接触到这个东东时,还以为只要完成操作就可以实现自定义分享了,随着各种坑不断,最后发现,微信JS SDK仅仅只是将我们的自定义内容临时缓存,当我们需要分享时,还是需要通过微信右上角的按钮来完成操作的。好嘞,不多讲废话了,进入今天的主题,接下来我将按照通过超链接完成新浪、QQ、QQ空间、腾讯微博分享,然后为大家奉上基于C#平台的微信JS SDK分享组件的签名逻辑,最后带领大家完成手机web端分享。
      进入第一点:通过超链接完成分享

      对于常用的社交平台我们基本可以通过超链接的方式进行内容分享,当然微信除外,微信不支持这种分享方式,这种分享方式可以便于我们自定义分享,并且使用起来非常的方便。

    function shareSina() {
            //分享到新浪微博
            var sharesinastring = 'http://service.weibo.com/share/share.php?title=' + $("#title").val() + '&url=' + $("#url").val();
            window.location.href = sharesinastring;
        }
        function shareQQzone(){
            var p = {
                url:location.href,
                showcount:'0',/*是否显示分享总数,显示:'1',不显示:'0' */
                desc:'',/*默认分享理由(可选)*/
                summary:'',/*分享摘要(可选)*/
                title:'',/*分享标题(可选)*/
                site:'满艺网',/*分享来源 如:腾讯网(可选)*/
                pics:'', /*分享图片的路径(可选)*/
                style:'203',
                98,
                height:22
            };
            //分享到QQ空间
            var sharesinastring = 'http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?title=' + $("#title").val() + '&url=' + $("#url").val() + '&site="满艺网"';
            window.location.href = sharesinastring;
        }
        function shareQQ() {
            var p = {
                url: location.href, /*获取URL,可加上来自分享到QQ标识,方便统计*/
                desc: '', /*分享理由(风格应模拟用户对话),支持多分享语随机展现(使用|分隔)*/
                title: '', /*分享标题(可选)*/
                summary: '', /*分享摘要(可选)*/
                pics: '', /*分享图片(可选)*/
                flash: '', /*视频地址(可选)*/
                site: '满艺网', /*分享来源(可选) 如:QQ分享*/
                style: '201',
                 32,
                height: 32
            };
            //分享到QQ
            var sharesinastring = 'http://connect.qq.com/widget/shareqq/index.html?title=' + $("#title").val() + '&summary=' + $("#url").val() + '&url=' + $("#url").val() + '&site="满艺网"';
            window.location.href = sharesinastring;
        }
        function shareQQweibo() {
            var p = {
                url: location.href, /*获取URL,可加上来自分享到QQ标识,方便统计*/
                title: '', /*分享标题(可选)*/
                pic: '', /*分享图片(可选)*/
                site: '满艺网' /*分享来源(可选) 如:QQ分享*/
            };
            //分享到腾讯微博
            var sharesinastring = 'http://v.t.qq.com/share/share.php?title=' + $("#title").val() + '&url=' + $("#url").val() + '&site="满艺网"';
            window.location.href = sharesinastring;
        }

      以上便是分享都新浪微博、QQ、QQ空间、腾讯微博的JS代码,我们只需要在页面需要分享的位置进行一下调用即可。当然还有很多平台,一样支持这种形式的分享内容,各位小伙伴自己去摸索吧,这里我们不再一一赘述。

      下面介绍一些微信分享:

      一开始我们便说道微信内置的浏览器右上角带有分享功能,这也导致我们在自己的网页上无法直接分享到微信的朋友圈,而微信为我们提供了一个用于微信自定义分享的JS SDK,小伙伴是不是已经按耐不住自己的激情了,下面我们来先简单看一这个JS SDK为何物?微信官方提供的文档到时挺详细,但是想要开发JS SDK我们首先需要一个微信公众号,然后我们点击“接口权限”可以查看到我们所拥有的权限,如下:

      

      对于上面这些基本的东西就不在多说,下面我们重点看一下如何获取jsapi_ticket,如何进行签名。官方文档提示的步骤是,先获取access_token,然后通过access_token来获取jsapi_ticket,最后通过jsapi_ticket进行签名。下面我们就一步一步完成上面的工作。注:官方提供了php、java、python、nodejs的实例程序,这里我将以C#为例为大家结束如何完成上面的操作。

      第一步、获取access_token

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

      

      第二步获取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

      

      获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。

      第三步生成JS-SDK权限验证的签名

      签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。

      

    注意事项

      1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同;

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

      3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。

      以上便是微信JS SDK的签名逻辑部分,下面奉上具体的代码实现:

    using System;
    using System.Net;
    using System.Web.Mvc;
    using System.IO;
    using System.Text;
    using System.Web.Script.Serialization;
    using ManYiAbyWAP.Models;
    
    /// <summary>
    /// 微信获取jsapi_ticket
    /// </summary>
    namespace ManYiAbyWAP.Controllers
    {
        public class WXMessageController : Controller
        {
            private static string APPID = "微信提供的appid";
            private static string SECRECT = "微信提供的secrect";
            public static WXInfo accessToken = null;//全局对象,每7200秒更新一次,微信对每日获取Token有请求次数与时效限制
            public static DateTime overTime = DateTime.Now;//用于Token的过期验证
    
            public ActionResult GetToken(string url) {
                if (accessToken != null)
                {
                    TimeSpan span = Convert.ToDateTime(overTime).Subtract(Convert.ToDateTime(DateTime.Now));
                    if (span.TotalHours > 2)
                    {
                        accessToken = GETWinXinToken();
                        overTime = DateTime.Now;
                    }
                }
                else
                {
                    accessToken = GETWinXinToken();
                    overTime = DateTime.Now;
                }
    
                //生成签名的时间戳
                TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                accessToken.timestamp = Convert.ToInt64(ts.TotalSeconds).ToString();
                //获取随机串
                accessToken.noncestr = createNonceStr(16);
    
                string str = "jsapi_ticket="+ accessToken .ticket+ "&noncestr="+ accessToken.noncestr + "&timestamp="+ accessToken.timestamp + "&url="+ url;
                accessToken.signature = SHA1(str).ToLower();
                accessToken.APPID = APPID;
                return Json(accessToken, JsonRequestBehavior.AllowGet);
            }
    
            //生成随机串
            private string createNonceStr(int length = 16)
            {
                string str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
                Random r = new Random();
                string result = string.Empty;
                //生成一个8位长的随机字符,具体长度可以自己更改
                for (int i = 0; i < length; i++)
                {
                    int m = r.Next(0, 62);//这里下界是0,随机数可以取到,上界应该是62,因为随机数取不到上界,也就是最大62,符合我们的题意
                    string s = str.Substring(m, 1);
                    result += s;
                }
                return result;
            }
    
            //散列算法
            private static string SHA1(string text)
            {
                byte[] cleanBytes = Encoding.Default.GetBytes(text);
                byte[] hashedBytes = System.Security.Cryptography.SHA1.Create().ComputeHash(cleanBytes);
                return BitConverter.ToString(hashedBytes).Replace("-", "");
            }
    
            //通过GET请求获取Token
            private static WXInfo GETWinXinToken() {
                //获取access_token
                HttpWebResponse response = CreateGetHttpResponse("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APPID + "&secret=" + SECRECT, 5000);
                StreamReader reader = new StreamReader(response.GetResponseStream());
                String line;
                StringBuilder sb = new StringBuilder();
                while ((line = reader.ReadLine()) != null)
                {
                    sb.Append(line.ToString());
                }
    
                JavaScriptSerializer js = new JavaScriptSerializer();
                WXInfo accessToken = js.Deserialize<WXInfo>(sb.ToString());
    
                //获取jsapi_ticket
                response = CreateGetHttpResponse("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken.access_token + "&type=jsapi", 5000);
                reader = new StreamReader(response.GetResponseStream());
                sb = new StringBuilder();
                while ((line = reader.ReadLine()) != null)
                {
                    sb.Append(line.ToString());
                }
                accessToken = js.Deserialize<WXInfo>(sb.ToString());
                return accessToken;
            }
    
            /// <summary>   
            /// 创建GET方式的HTTP请求   
            /// </summary>   
            /// <param name="url">请求的URL</param>   
            /// <param name="timeout">请求的超时时间</param>   
            /// <param name="userAgent">请求的客户端浏览器信息,可以为空</param>   
            /// <param name="cookies">随同HTTP请求发送的Cookie信息,如果不需要身份验证可以为空</param>   
            /// <returns></returns>   
            public static HttpWebResponse CreateGetHttpResponse(string url, int? timeout, string userAgent=null, CookieCollection cookies=null)
            {
                if (string.IsNullOrEmpty(url))
                {
                    throw new ArgumentNullException("url");
                }
                HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
                request.Method = "GET";
                if (!string.IsNullOrEmpty(userAgent))
                {
                    request.UserAgent = userAgent;
                }
                if (timeout.HasValue)
                {
                    request.Timeout = timeout.Value;
                }
                if (cookies != null)
                {
                    request.CookieContainer = new CookieContainer();
                    request.CookieContainer.Add(cookies);
                }
                return request.GetResponse() as HttpWebResponse;
            }
        }
    }

      用于存放Token信息的全局对象WXInfo.cs

    namespace ManYiAbyWAP.Models
    {
        /// <summary>
        /// 微信获取Token返回参数类
        /// </summary>
        public class WXInfo
        {
            public string APPID { get; set; }
    
            public string access_token { get; set; }//access_token
            public string expires_in { get; set; }//Token过期时间,7200秒内有效
    
            public string ticket { get; set; }//jsapi_ticket
            public string errmsg { get; set; }
            public int errcode { get; set; }
    
            public string noncestr { get; set; }//生成签名的随机串
            public string timestamp { get; set; }//生成签名的时间戳
            public string signature { get; set; }//签名返回值
        }
    }

      网页端进行初始化的JS代码:

    //微信JS SDK请求状态
        var requestStatus = 0;
        function shareWX() {
            if (requestStatus != 1) {
                requestStatus = 1;//正在请求
                var ajaxPara = "url=" + encodeURIComponent(window.location.href.split('#')[0]);
                $.ajax({
                    url: '/WXMessage/GetToken',
                    dataType: 'json',
                    data: ajaxPara,
                    success: function (json) {
                        if (undefined != json && json !== "") {
                            var jsonObjs = eval(json);
                            wx.config({
                                debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                                appId: jsonObjs.APPID, // 必填,公众号的唯一标识
                                timestamp: jsonObjs.timestamp, // 必填,生成签名的时间戳
                                nonceStr: jsonObjs.noncestr, // 必填,生成签名的随机串
                                signature: jsonObjs.signature,// 必填,签名,见附录1
                                jsApiList: [
                                    'checkJsApi',
                                    'onMenuShareTimeline',
                                    'onMenuShareAppMessage',
                                    'onMenuShareQQ',
                                    'onMenuShareWeibo',
                                    'onMenuShareQZone'
                                ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
                            });
                            wx.ready(function () {
                                //alert("微信验证成功");
                                // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
    
                                wx.checkJsApi({
                                    jsApiList: [
                                        'checkJsApi',
                                        'onMenuShareTimeline',
                                        'onMenuShareAppMessage',
                                        'onMenuShareQQ',
                                        'onMenuShareWeibo',
                                        'onMenuShareQZone'
                                    ], // 需要检测的JS接口列表,所有JS接口列表见附录2,
                                    success: function (res) {
                                        // 以键值对的形式返回,可用的api值true,不可用为false
                                        // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
                                    }
                                });
    
                                wx.onMenuShareWeibo({
                                    title: '满艺网分享测试', // 分享标题
                                    desc: '满艺网分享描述测试', // 分享描述
                                    link: 'http://www.manyiaby.com', // 分享链接
                                    imgUrl: 'http://www.manyiaby.com/img/logo_2.jpg', // 分享图标
                                    success: function () {
                                        // 用户确认分享后执行的回调函数
                                        alert("分享成功");
                                    },
                                    cancel: function () {
                                        // 用户取消分享后执行的回调函数
                                        alert("分享取消");
                                    }
                                });
    
                            });
                            wx.error(function (res) {
                                //alert("微信验证失败 res:"+res);
                                // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
                            });
                            requestStatus = 2;//请求完成
                        }
                    },
                    complete: function () {
                        window.setTimeout(function () {
                            requestStatus = 2;//请求完成
                        }, 300);
                    }
                });
            }

      到这里关于微信分享JS SDK的使用就为大家介绍完毕,大家可以结合自己的需求进行参考。一开始已经为大家介绍了,微信提供的分享JS SDK仅仅只是一个对于微信内部浏览器的缓存处理,真正的分享还是需要我们点击右上角的分享按钮。

      上面这些都不是太完美的手机web分享解决方法,最后给大家介绍一些Sosh社会化分享组件,当我看到这个组件时,我就知道这是我需要的,简洁的界面,整好可以让我们的网站看起来典雅舒服。好了,废话不多说,进入主题:

      

      如何使用呢?我们只需要在页面引入即可,这里我为大家提供一个精简版下载链接,方便大家的开发使用,集成非常方便。

      ok,今天关于网页社会化分享的内容就为大家介绍完了,如有不当之处,还望斧正。

      

  • 相关阅读:
    LeetCode:204. 计数质数
    LeetCode:203. 移除链表元素
    LeetCode:202. 快乐数
    LeetCode:191. 位1的个数
    LeetCode:190. 颠倒二进制位
    LeetCode:189. 旋转数组
    LeetCode:187. 重复的DNA序列
    LeetCode:165. 比较版本号
    LeetCode:164. 最大间距
    LeetCode:155. 最小栈
  • 原文地址:https://www.cnblogs.com/AndroidJotting/p/5787570.html
Copyright © 2020-2023  润新知