微信内置浏览器 用 JS 调用微信APP分享到微信朋友圈

   昨天开始搞分享到微信朋友圈,要求直接调用微信APP的分享到朋友圈。。。

   1:首先你需要完成微信的六大前期准备工作,这也是最烦人的。请仔细阅读微信的APP文档:

   文档地址:https://mp.weixin.qq.com/wiki/11/74ad127cc054f6b80759c40f77ec03db.html

  

   


  1.1  绑定域名 这种东西,需要注册,需要实名制,还不能注册为个人模式,要不不给接口使用权限,请注意...

         最终的要是你需要 有域名,还有获取 微信给你的2个 值 ,AppId 和 AppSecret

  1.2, 这个简单,看文档就好

  1.3:这个按照他的方式 ,我实现的代码如下:缓存什么的我就没写了,因为只是Demo,jsapi_ticket每天只能获取2000次,如果你只是研发应该够用

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace HuaSharp.SunCms.WebSite.RongYM
{
    public partial class wxTest : System.Web.UI.Page
    {

        //公众号ID,为了获取还需要拿自己的微信去注册,各种验证实名制,尼玛真麻烦
        public static string AppId = "wxea8cd26d4b77ebd9";
        //公众号的密钥 ,注册后各种操作登录后获得.
        public static string AppSecret = "01187a13372d431a398458ec49b77a10";

        //全局缓存对象  有效时间 2小时   微信JS接口的临时票据
        public static string jsapi_ticket = "";

        //用它来获取  jsapi_ticket ,它的有效期也是2小时,开发者必须在自己的服务全局缓存access_token , 它的值是通过接口获得的.
        //access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token
        //access_token的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新access_token的接口,这样便于业务服务器在API调用获知access_token已超时的情况下,可以触发access_token的刷新流程
        public static string access_token = "";

        //傻逼微信还需要传入时间撮来完成它的机密算法 
        public static string timestamp = "";

        //傻逼微信还需要传入当前页面的url来完成它的加密算法
        public static string curUrl = "";

        //尼玛,还需要一个随机串,来给它完成加密验证,恶心死了
        public static string noncestr = "zyq";

        //上面那么多垃圾东西,那么多次访问httpget,那么多次缓存,就是为了这个垃圾签名.
        public static string signature = "";

        protected void Page_Load(object sender, EventArgs e)
        {
            // access_token = "nC_O_2yUvP0CEcstb2wfTpP-zEOfJEyggcEWvrwAO1sO8H1TRpgjCJBmOPqCepcUOz64r0SKI8UTSSgY5Y8tmicCMZ3MKaATYVwppHXOiwmWOTImxDkIUMx1GEoO3MkaGDZfAEAURN";
            if (string.IsNullOrWhiteSpace(access_token))
            {   //获取access_token
                string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + AppId + "&secret=" + AppSecret;
                string result = GetHttp(url, this.Context);

                wxApiModel xwapi = JsonToObj(result, typeof(wxApiModel)) as wxApiModel;
                access_token = xwapi.access_token;
                //{ "access_token":"RlUQfwT7ALMEhpd7d-lwwdVl1L-shnlpR0f52dZdGTgETMXDik6kSlbsn0YywWDyt2DhcUo7bprg6lpfuCrdF3tDFlUrpj8Gt17jnuTxNBmW0HzTa7HWxYqLzX7AayvVPFSgAIADTG","expires_in":7200}
            }

            // jsapi_ticket = "kgt8ON7yVITDhtdwci0qeRexnVHaoFgZBri5CQ_FeuE26sRqPoRdqWba5z2zCcjWdvw70MKC3YJAvK9ieHSo7w";
            //用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket
            if (string.IsNullOrWhiteSpace(jsapi_ticket))
            {
                string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi";
                string result = GetHttp(url, this.Context);
                wxApiModel xwapi = JsonToObj(result, typeof(wxApiModel)) as wxApiModel;

                jsapi_ticket = xwapi.ticket;
                //{
                //    "errcode": 0,
                //    "errmsg": "ok",
                //    "ticket": "kgt8ON7yVITDhtdwci0qeRexnVHaoFgZBri5CQ_FeuHhRjNuvsKJ2ewt9V8iAZa2aorvGWgaPOgJkmRG442DZg",
                //    "expires_in": 7200
                //}
            }

            timestamp = GenerateTimeStamp();

            curUrl = this.Request.Url.ToString();
            //string param = "jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value";
            string param = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + curUrl;
            //通过SHA1加密算法获得签名
            signature = FormsAuthentication.HashPasswordForStoringInConfigFile(param, "SHA1");
        }


        public static string GetHttp(string url, HttpContext httpContext)
        {

            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);

            httpWebRequest.ContentType = "application/json";
            httpWebRequest.Method = "GET";
            httpWebRequest.Timeout = 20000;

            HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream());
            string responseContent = streamReader.ReadToEnd();

            httpWebResponse.Close();
            streamReader.Close();

            return responseContent;
        }

        /// <summary>
        /// 获取时间撮
        /// </summary>
        /// <returns></returns>
        public static string GenerateTimeStamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds).ToString();
        }

        /// <summary>
        /// 把JSON 格式 转换成List<Model>
        /// </summary>
        /// <param name="json"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static Object JsonToObj(String json, Type t)
        {
            try
            {
                System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(t);
                using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
                {
                    return serializer.ReadObject(ms);
                }
            }
            catch
            {
                return null;
            }
        }

    }

    public class wxApiModel
    {
        public string access_token { get; set; }

        public string expires_in { get; set; }

        public string errcode { get; set; }

        public string errmsg { get; set; }

        public string ticket { get; set; }
    }
}


然后前台代码如下:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="wxTest.aspx.cs" Inherits="HuaSharp.SunCms.WebSite.RongYM.wxTest" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
    <script type="text/javascript">
        
           wx.config({
                debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                appId: '<%=AppId%>', // 必填,公众号的唯一标识
                timestamp: <%=timestamp%>, // 必填,生成签名的时间戳
                nonceStr: '<%=noncestr%>', // 必填,生成签名的随机串
                signature: '<%=signature%>',// 必填,签名,见附录1
                jsApiList: ['onMenuShareTimeline'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2  onMenuShareTimeline =微信分享到朋友圈,APi地址:
           });

        window.onload=function(){ 

            alert("当前域名是:<%=curUrl%>");
        }



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

        wx.error(function(res){

            alert("微信接口初始化失败;错误信息:"+res);
            // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。

        });


        function Demo()
        {
            //alert("123");
            wx.checkJsApi({
                jsApiList: ['onMenuShareTimeline'], // 需要检测的JS接口列表,所有JS接口列表见附录2,
                success: function(res) {
                    alert(res);
                    debugger;
                    // 以键值对的形式返回,可用的api值true,不可用为false
                    // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
                }
            });
        }

        function Demo2()
        {
            wx.onMenuShareTimeline({
                debug: true,
                title: '微信测试分享', // 分享标题
                link: 'http://rym.huasharp.com/RongYM/wxTest.aspx', // 分享链接
                imgUrl: 'http://rym.huasharp.com/UploadFiles/20170414111448.jpg', // 分享图标
                success: function () { 
                    // 用户确认分享后执行的回调函数
                    alert("分享成功");
                },
                cancel: function () { 
                    // 用户取消分享后执行的回调函数
                    alert("分享失败");
                },
                complete:function()
                {
                    alert("complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。");
                }
            });

            //alert('已注册获取“分享到朋友圈”状态事件');
        }
        
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <input type="button" style=" width;200px;height:200px " value="微信测试" onclick="Demo()"/>
        <input type="button" style=" width;200px;height:200px "  value="微信朋友圈测试" onclick="Demo2()"/>


    </div>
           <input type="button" style=" width;200px;height:200px " class="btn btn_primary" id="onMenuShareTimeline" value="onMenuShareTimeline"></input>
    </form>
</body>
</html>


然后 就可以运行了,在这里我要告诉大家千万要注意的地方

1:有一个比较好的测试工具,在你登录微信公众平台以后,在左边导航有个开发者工具,记得去使用


2:接口权限:正式环境的话,这些接口权限是需要开通的.当然是企业类型的账号,开通以后的样子是这样的:



3:看到第2点是不是怕了?没关系,如果你是开发者的话,在开发工具中有一个测试账号,它拥有大部分权限:



4:测试账号需要注意的地方(你需要有域名,并且在有域名的机器上调试最后一部分,怕了吧?微信的要求就是这么严格,还有注意事项请看图片)



5:请使用微信模拟开发工具,如果你不怕麻烦,用手机直接测试也是可以的.不过功能没这个强大,下载地址在开发者工具里面,具体可以参考这个百度经验:

http://jingyan.baidu.com/article/77b8dc7f9d341f6174eab6ee.html


6:微信接口调用成功以后会有errMess提示,千万被err这几个字给迷惑住,其实是成功了,还有可能会保域名无效错误,这个你需要检查你的域名。




7: 微信分享朋友圈执行了以后,并不是直接调用打开微信app,而是还是需要手动点击右上角的分享.感觉功能真的是弱爆了,搞了这么久。建议大家初始化以后,用户点击分享按钮以后,你提示他使用右上角,初始化分享朋友圈和不分享的区别可以见下图:


这个是没有初始化设置朋友圈分享的页面




8:到这里就结束了,分享成功以后,会有回调方法,我发现我的iphone7 不支持。但是安卓机是支持的....无语了,最后希望微信越做越好。功能越来越强大,不像现在这么麻烦。。。还有这里用的是微信内置浏览器,微信内置浏览器就是说在微信中点击链接,打开的浏览器...好弱... 因为苹果的不开源,苹果上很多浏览器都不支持...UC浏览器还算支持分享到朋友圈的.

有问题可以加我QQ 10200454 询问,我也被这个坑了一天...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章