微信公众号 - 网页服务 - 分享接口

  • 需要有一个认证的微信公众号,订阅号、服务号都可以,主体不能是”个人“
  • 需要有一个域名,域名不能含有中文,域名需要备案

目录

一、公众号与域名绑定

二、 IP白名单

三、准备工作

3.1 引入JS文件

四、 后端(.net)生成需要的参数

4.1 获取accessToken

4.2 获取jsapi_ticket

4.3 生成其他参数

4.4 验证签名工具

五、前端配置

5.1 基本配置

5.2 分享到朋友圈

5.3 分享给朋友

5.4 分享到QQ

5.5 分享到腾讯微博

5.6 分享到QQ空间

六、测试环境


一、公众号与域名绑定

  • 微信公众平台链接:https://mp.weixin.qq.com/
  • 登录到公众号,找到 设置 => 公众号设置 => 功能设置 => JS接口安全域名
  • 将txt下载下来,放到域名目录,将域名填入

二、 IP白名单

  • 登录到公众号,找到 开发 => 基本配置 => IP白名单 ,将本地的IP和服务器的IP一起加上

三、准备工作

3.1 引入JS文件

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
  • 根据需求引用http或https的文件

四、 后端(.net)生成需要的参数

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

4.1 获取accessToken

/// <summary>
/// 获取access_token
/// </summary>
/// <returns></returns>
public static AccessTokenViewModel GetToken()
{
    var url = "https://api.weixin.qq.com/cgi-bin/token";

    Dictionary<string, string> dict = new Dictionary<string, string>();
    dict.Add("appid", appId); // 公众号开发者ID(AppID)
    dict.Add("secret", secret); // 公众号开发者密码(AppSecret)
    dict.Add("grant_type", "client_credential");

    return WebService<AccessTokenViewModel>(dict, url);
}

/// <summary>
/// 微信接口运行接口参数
/// <parm>错误码查看:https://blog.csdn.net/qq_31267183/article/details/83211972</parm>
/// </summary>
public class WxResult
{
    /// <summary>
    /// 错误代码
    /// </summary>
    public int errcode { get; set; }

    /// <summary>
    /// 错误描述
    /// </summary>
    public string errmsg { get; set; }
}

/// <summary>
/// 获取Token返回参数
/// </summary>
public class AccessTokenViewModel : WxResult
{
    /// <summary>
    /// 网页授权接口调用凭证
    /// </summary>
    public string access_token { get; set; }

    /// <summary>
    /// access_token接口调用凭证超时时间,单位(秒)
    /// </summary>
    public string expires_in { get; set; }

    /// <summary>
    /// 用户刷新access_token
    /// </summary>
    public string refresh_token { get; set; }

    /// <summary>
    /// 用户唯一标识,在未观众公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的openid
    /// </summary>
    public string openid { get; set; }

    /// <summary>
    /// 用户授权的作用域,使用逗号分隔
    /// </summary>
    public string scope { get; set; }
}

/// <summary>
/// 远程获取链接
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dic">参数</param>
/// <param name="url">链接地址</param>
/// <returns></returns>
public dynamic WebService<T>(Dictionary<string, string> dic, string url)
{
    var param = "";
    foreach (var item in dic)
    {
        if (!string.IsNullOrEmpty(param))
            param += "&";

        param += item.Key + "=" + item.Value;
    }
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + (param == "" ? "" : "?") + param);
    request.Method = "GET";
    request.ContentType = "text/html;charset=UTF-8";

    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    Stream myResponseStream = response.GetResponseStream();
    StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
    string retString = myStreamReader.ReadToEnd();
    myStreamReader.Close();
    myResponseStream.Close();

    var res = JsonConvert.DeserializeObject<T>(retString);
    return res;
}

4.2 获取jsapi_ticket

/// <summary>
/// 获取jsapi_ticket
/// </summary>
/// <param name="access_token"></param>
/// <returns></returns>
public static JsapiTicketViewModel GetTicket(string access_token)
{
    var url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";

    Dictionary<string, string> dict = new Dictionary<string, string>();
    dict.Add("access_token", access_token);
    dict.Add("type", "jsapi");

    return WebService.HttpGet<JsapiTicketViewModel>(dict, url);
}

/// <summary>
/// 微信接口运行接口参数
/// <parm>错误码查看:https://blog.csdn.net/qq_31267183/article/details/83211972</parm>
/// </summary>
public class WxResult
{
    /// <summary>
    /// 错误代码
    /// </summary>
    public int errcode { get; set; }

    /// <summary>
    /// 错误描述
    /// </summary>
    public string errmsg { get; set; }
}

/// <summary>
/// 获取jsapi_ticket返回参数
/// </summary>
public class JsapiTicketViewModel : WxResult
{
    /// <summary>
    /// ticket
    /// </summary>
    public string ticket { get; set; }

    /// <summary>
    /// 有效时长
    /// </summary>
    public int expires_in { get; set; }
}
/// <summary>
/// 远程获取链接
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dic">参数</param>
/// <param name="url">链接地址</param>
/// <returns></returns>
public dynamic WebService<T>(Dictionary<string, string> dic, string url)
{
    var param = "";
    foreach (var item in dic)
    {
        if (!string.IsNullOrEmpty(param))
            param += "&";

        param += item.Key + "=" + item.Value;
    }
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + (param == "" ? "" : "?") + param);
    request.Method = "GET";
    request.ContentType = "text/html;charset=UTF-8";

    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    Stream myResponseStream = response.GetResponseStream();
    StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
    string retString = myStreamReader.ReadToEnd();
    myStreamReader.Close();
    myResponseStream.Close();

    var res = JsonConvert.DeserializeObject<T>(retString);
    return res;
}

4.3 生成其他参数

/// <summary>
/// 获取jssdk所需签名
/// </summary>
/// <param name="ticket"></param>
/// <param name="url">要显示的url链接</param>
/// <returns></returns>
public static string Signature(string url)
{
    HttpCookie codeCookie = HttpContext.Current.Request.Cookies[cookieName];
    if (codeCookie != null)
    {
        return "";
    }

    string noncestr = RandomNumber(16); // 随机数
    long timestamp = GetTimestamp(DateTime.Now);

    AccessTokenViewModel token = GetToken();
    JsapiTicketViewModel getTicket = GetTicket(token.access_token);

    var ticket = getTicket.ticket;

    string string1 = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
    string signature = FormsAuthentication.HashPasswordForStoringInConfigFile(string1, "SHA1").ToLower();

    return signature;
}

/// <summary>
/// 生成验证码
/// </summary>
/// <param name="length">指定验证码的长度</param>
/// <returns></returns>
public string RandomNumber(int length)
{
    int[] randMembers = new int[length];
    int[] validateNums = new int[length];
    string validateNumberStr = "";

    char[] oCharacter = {'0','1','2','3','4','5','6','7','8','9',
        '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'
    };
    int iSeed = DateTime.Now.Millisecond;
    Random random = new Random(iSeed);
    for (int i = 0; i < length; i++)
    {
        validateNumberStr += oCharacter[random.Next(oCharacter.Length)];
    }
    return validateNumberStr;
}

/// <summary>
/// 获取1970-01-01至dateTime的毫秒数
/// 10位
/// </summary>
public long GetTimestamp(DateTime dateTime)
{
    DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, 0);
    return (dateTime.Ticks - dt.Ticks) / 10000000;
}

4.4 验证签名工具

  • 将字段传入,验证程序得到的signature是否正确

五、前端配置

5.1 基本配置

<script>
// 参数名大小写要一致
wx.config({
    debug: true, // 是否要调试,发布到正式时改成false
    appId: '', // 公众号开发者ID,与后端参与签名的字段一致
    timestamp: '', // 时间戳,与后端参与签名的字段一致
    nonceStr: '', // 随机数,与后端参与签名的字段一致
    signature: '', // 签名,与后端参与签名的字段一致
    jsApiList: [        
        "onMenuShareTimeline", // 分享到朋友圈
        "onMenuShareAppMessage", // 分享给朋友
        "onMenuShareQQ", // 分享到QQ
        "onMenuShareWeibo", // 分享到腾讯微博
        "onMenuShareQZone", // 分享到QQ空间
    ]
});

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

wx.error(function (res) {
    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
</script>

5.2 分享到朋友圈

<script>
function _shareTimeline() {
    // 页面加载后设置微信分享到朋友圈的内容
    wx.onMenuShareTimeline({
        title: '', // 分享标题
        link: location.href, // 分享链接(当前页面URL),与后端参与签名的字段一致
        imgUrl: '', // 分享图标,建议 300*300px
        success: function () {
            // 用户确认分享后执行的回调函数
        },
        cancel: function () {
            // 用户取消分享后执行的回调函数
        }
    });
}
</script>

5.3 分享给朋友

<script>
function _shareAppMessage() {
    // 页面加载后设置微信分享给朋友的内容
    wx.onMenuShareAppMessage({
        title: '', // 分享标题
        desc: '', // 分享描述
        link: location.href, // 分享链接(当前页面URL),与后端参与签名的字段一致
        imgUrl: '', // 分享图标,建议 300*300px
        type: '', // 分享类型,music、video或link,不填默认为link
        dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
        success: function () {
            // 用户确认分享后执行的回调函数
        },
        cancel: function () {
            // 用户取消分享后执行的回调函数
        }
    });
}
</script>

5.4 分享到QQ

<script>
function _shareQQ() {
    // 页面加载后设置微信分享到QQ的内容
    wx.onMenuShareQQ({
        title: '', // 分享标题
        desc: '', // 分享描述
        link: location.href, // 分享链接(当前页面URL),与后端参与签名的字段一致
        imgUrl: '', // 分享图标,建议 300*300px
        success: function () {
            // 用户确认分享后执行的回调函数
        },
        cancel: function () {
            // 用户取消分享后执行的回调函数
        }
    });
}
</script>

5.5 分享到腾讯微博

<script>
function _shareWeibo() {
    // 页面加载后设置微信分享到腾讯微博的内容
    wx.onMenuShareWeibo({
        title: '', // 分享标题
        desc: '', // 分享描述
        link: location.href, // 分享链接(当前页面URL),与后端参与签名的字段一致
        imgUrl: '', // 分享图标,建议 300*300px
        success: function () {
            // 用户确认分享后执行的回调函数
        },
        cancel: function () {
            // 用户取消分享后执行的回调函数
        }
    });
}
</script>

5.6 分享到QQ空间

<script>
function _shareQZone() {
    // 页面加载后设置微信分享到QQ空间的内容
    wx.onMenuShareWeibo({
        title: '', // 分享标题
        desc: '', // 分享描述
        link: location.href, // 分享链接(当前页面URL),与后端参与签名的字段一致
        imgUrl: '', // 分享图标,建议 300*300px
        success: function () {
            // 用户确认分享后执行的回调函数
        },
        cancel: function () {
            // 用户取消分享后执行的回调函数
        }
    });
}
</script>

六、测试环境

猜你喜欢

转载自blog.csdn.net/qq_31267183/article/details/84424278