你好呀~欢迎关注微信公众号:python入门到放弃

一次微信网页开发(分享)的坑

.Net错误 admin 385浏览

记一次微信网页开发(分享)的坑

本文记录开分微信网页中分享的注意事项。
微信官方文档

阅读目录

前期准备用C#获取微信签名前端js脚本遇到的问题

前期准备

1、网页需要绑定一个公众号
2、公众号后台需要设置IP白名单
3、公众号后台需要设置JS接口安全域名

用C#获取微信签名

简单记录如下:

public class WechatShareHelpler
    {

        /// <summary>
        ///  appid / secret
        /// </summary>
        private readonly string appid = "";
        private readonly string secret = "";

        private readonly HttpHelplerProvider _client;

        public WechatShareHelpler()
        
{
            _client = new HttpHelplerProvider();
        }

        public async Task<string> GetToken()
        {
            var token = cacheOp.GetCache("wechattoken");
            if (token != null)
            {
                return token.ToString();
            }
            string url = "https://api.weixin.qq.com/cgi-bin/token";
            var querydata = new Dictionary<stringstring> {
                { "grant_type","client_credential" },
                { "appid",appid },
                { "secret",secret}
            };
            var response = await _client.GetByQueryStringAsync(url, querydata);
            var result = await response.Content.ReadAsAsync<AccessToken>();
            cacheOp.SetCache("wechattoken", result.access_token,null,DateTime.Now.AddSeconds(7200));
            return result.access_token;
        }

        public async Task<string> GetTicket()
        {
            string token = await GetToken();
            string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
            var querydata = new Dictionary<stringstring> {
                { "access_token",token },
                { "type","jsapi" }
            };
            var response = await _client.GetByQueryStringAsync(url, querydata);
            var result = await response.Content.ReadAsAsync<jsapiticketModel>();
            return result.ticket;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="dir"></param>
        /// <returns></returns>
        public string AsciiDicToStr(Dictionary<stringstring> dir)
        
{
            string[] arrKeys = dir.Keys.ToArray();
            Array.Sort(arrKeys, string.CompareOrdinal);
            var sb = new StringBuilder();
            foreach (var key in arrKeys)
            {
                string value = dir[key];
                sb.Append(key + "=" + value + "&");
            }
            return sb.ToString().Substring(0, sb.ToString().Length - 1);
        }

        public async Task<resultModel> GetSignature(string url)
        {
            string noncestr = new WxHelper().GetRandomString(16);
            string jsapi_ticket = await GetTicket();
            string timestamp = GetTimeStamp();
            Dictionary<stringstring> keyValuePairs = new Dictionary<stringstring> {
                { "noncestr",noncestr},
                { "jsapi_ticket",jsapi_ticket},
                { "timestamp",timestamp},
                { "url",url}
            };
            string str = AsciiDicToStr(keyValuePairs);
            return new resultModel
            {
                jsapi_ticket = jsapi_ticket,
                signature = Sha1Signature(str).ToLower(),
                noncestr = noncestr,
                timestamp = timestamp
            };
        }
        public string GetTimeStamp()
        
{
            TimeSpan ts = DateTime.Now - new DateTime(1970110000);
            return Convert.ToInt64(ts.TotalSeconds).ToString();
        }
        public static string Sha1Signature(string str)
        
{
            var buffer = Encoding.UTF8.GetBytes(str);
            var data = SHA1.Create().ComputeHash(buffer);

            StringBuilder sub = new StringBuilder();
            foreach (var t in data)
            {
                sub.Append(t.ToString("X2"));
            }

            return sub.ToString();
        }

    }


    public class jsapiticketModel
    {

        public int errcode { get; set; }
        public string errmsg { get; set; }
        public string ticket { get; set; }
        public int expires_in { get; set; }
    }

    public class resultModel
    {

        public string signature { get; set; }
        public string noncestr { get; set; }
        public string jsapi_ticket { get; set; }
        public string timestamp { get; set; }

    }

其中用到的HttpHelplerProvider类来自:HttpClient使用
需要安装:System.Net.Http.Formatting.Extension
缓存需要自行修改。

前端js脚本

1、需要引用官方js脚本(http://res2.wx.qq.com/open/js/jweixin-1.6.0.js)
2、自行写一个分享js

/*
 * 
 * 
 *  
 *  shareData = {
 *          url: '',// 当前页面url
            title: '', // 分享标题
            desc: '', // 分享描述  自定义“分享到朋友圈”及“分享到QQ空间”按钮的分享内容 无
            link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
            imgUrl: '', // 分享图标
            success: function () {
                // 设置成功
            },(非必填)
            fail: function, // 分享失败回调(非必填)
            cancelfunction, // 取消分享回调(非必填)
    }
 * 
 */


// 统一分享入口
function wxShareConfigInfo(shareData)
 {
    console.log(shareData);
    $.ajax({
        url: "",
        data: { url: shareData["url"] },
        dataType: "JSON",
        type"POST",
        async: false,
        success: function (res) {
            wx.config({
                debugfalse, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                appId: '', // 必填,公众号的唯一标识
                timestamp: res.timestamp, // 必填,生成签名的时间戳
                nonceStr: res.noncestr, // 必填,生成签名的随机串
                signature: res.signature,// 必填,签名
                jsApiList: ["updateAppMessageShareData""updateTimelineShareData""onMenuShareWeibo"] // 必填,需要使用的JS接口列表
            });
        }
    });
    wx.ready(function () {
        delete shareData["url"];
        //func(shareData);
        wx.updateAppMessageShareData(shareData);
        wx.onMenuShareWeibo(shareData);
        delete shareData["desc"];
        wx.updateTimelineShareData(shareData);
    });
    wx.error(function (res) {
        console.log(res);
        //alert("error");
    });
}

遇到的问题

1、签名错误问题

  • 首先在签名验证 验证自己的签名是否正确
  • 确定前端,后端的appid是一致的。
  • 确定公众号配置的js接口安全域名 是不带https的。
  • 确定前端传递的url,如果带有中文,需要编码,该url包含https,但是不包含#及后面的部分。
  • 在微信测试工具上正常,在手机上不行(如果页面存在iframe可能会出现这样的情况。)

转载请注明: 十三 » 一次微信网页开发(分享)的坑

喜欢 (1) or 分享 ( 0)