- 需要有一个认证的微信公众号,订阅号、服务号都可以,主体不能是”个人“
- 需要有一个域名,域名不能含有中文,域名需要备案
目录
一、公众号与域名绑定
二、 IP白名单
三、准备工作
3.1 引入JS文件
四、 后端()生成需要的参数
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/
- 登录到公众号,找到 设置 => 公众号设置 => 功能设置 => JS接口安全域名
- 将txt下载下来,放到域名目录,将域名填入
二、 IP白名单
- 登录到公众号,找到 开发 => 基本配置 => IP白名单 ,将本地的IP和服务器的IP一起加上
三、准备工作
- 官方文档:https://qydev.weixin.qq/wiki/index.php?title=%E5%BE%AE%E4%BF%A1JS%E6%8E%A5%E5%8F%A3
3.1 引入JS文件
<script src="http://res.wx.qq/open/js/jweixin-1.0.0.js"></script>
<script src="https://res.wx.qq/open/js/jweixin-1.0.0.js"></script>
-
根据需求引用http或https的文件
四、 后端()生成需要的参数
- 微信错误码查看:https://blog.csdn/qq_31267183/article/details/83211972
<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/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/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/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/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 + "×tamp=" + 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 验证签名工具
- 官方地址:https://mp.weixin.qq/debug/cgi-bin/sandbox?t=jsapisign
- 将字段传入,验证程序得到的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>
六、测试环境
- 使用微信web开发者工具:https://developers.weixin.qq/miniprogram/dev/devtools/download.html
- 选择“公众号网页项目”,登录微信公众号运营者的微信,即可测试,该工具与谷歌浏览器操作一致
更多推荐
微信公众号 - 网页服务 - 分享接口
发布评论