uniapp中针对H5端做微信分享功能总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uniapp中针对H5端做微信分享功能总结相关的知识,希望对你有一定的参考价值。
参考技术A1.引入jweixin-module
2.初始化微信分享配置流程
3.在需要分享的页面中调用初始化微信配置方法
uniapp h5+webapi 实现微信浏览器的自定义分享(微信JSSDK)
公众号配置
第一步:配置js安全域名(微信公众平台=>公众号设置=>功能设置=>js接口安全域名)
第二步:配置白名单(微信公众平台=>基本配置=>ip白名单=>查看,配置多ip,可以换行输入),如果是本地测试,可以在百度中搜索ip,获取本地公网IP地址
webapi
第一步:获取access_token,access_token是获取其他接口信息的钥匙,所有接口都需要调用access_token
AccessToken.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Script.Serialization;//需要添加System.Web.Extensions引用
namespace Third.WeChat
{
/// <summary>
/// 获取微信token的类(获取access_token,access_token是获取其他接口信息的钥匙,所有接口都需要调用access_token)
/// @Author LiKely
/// @Date 2019-9-18 20:17:39
/// </summary>
public static class AccessToken
{
/// <summary>
/// 拉取AccessToken,微信每天公共2000次AccessToken的获取,所以需要缓存AccessToken
/// </summary>
/// <returns>用户凭证:AccessToken</returns>
public static string GetTokenCache(string appid, string appsecret)
{
string TokenCache;
if (HttpContext.Current.Cache["AccessToken"] != null)
{
TokenCache = HttpContext.Current.Cache["AccessToken"].ToString();
}
else
{
TokenCache = AddTokenCache(appid, appsecret);
}
return TokenCache;
}
/// <summary>
/// 将AccessToken添加到缓存
/// </summary>
/// <returns>AccessToken</returns>
private static string AddTokenCache(string appid, string appsecret)
{
//获取AccessToken
string AccessToken = GetAccessToken(appid, appsecret);
HttpContext.Current.Cache.Insert("AccessToken", AccessToken,null,DateTime.Now.AddSeconds(7200),TimeSpan.Zero);
return AccessToken;
}
/// <summary>
/// 获取AccessToken
/// </summary>
/// <returns>AccessToken</returns>
private static string GetAccessToken(string appid, string appsecret)
{
string accessToken = "";
string respText = "";
string url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appid, appsecret);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream resStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(resStream, Encoding.Default);
respText = reader.ReadToEnd();
resStream.Close();
}
JavaScriptSerializer jss = new JavaScriptSerializer();
Dictionary<string, object> respDic = (Dictionary<string, object>)jss.DeserializeObject(respText);
accessToken = respDic["access_token"].ToString();
return accessToken;
}
}
}
第二步:验证权限我们需要获取四个参数appId、timestamp、nonceStr、signature,jsapi_ticket获取到jsapi_ticket有效时间为7200s
JsapiTicket.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Security;
using System.Net;
using System.IO;
using Model.Third.WeChat;
using System.Web.Script.Serialization;//需要添加System.Web.Extensions引用
namespace Third.WeChat.business
{
/// <summary>
/// 获取微信Jssdk分享签名信息的参数
/// @Author LiKely
/// @Date 2019-9-18 20:21:51
/// </summary>
public static class JsapiTicket
{
private static JavaScriptSerializer jss = new JavaScriptSerializer();
/// <summary>
/// 获取JsApi权限配置的数组/四个参数
/// </summary>
/// <param name="AppId"></param>
/// <param name="AppSecret"></param>
/// <param name="reqUrl">当前的地址</param>
/// <returns></returns>
public static JsapiTicketInfo GetObject(string AppId, string AppSecret, string reqUrl)
{
string jsapi_ticket = "";
string access_token = "";
//ticket 缓存7200秒
if (System.Web.HttpContext.Current.Cache["jsapi_ticket"] != null)
{
access_token = AccessToken.GetTokenCache(AppId, AppSecret);
jsapi_ticket = System.Web.HttpContext.Current.Cache["jsapi_ticket"].ToString();
}
else
{
access_token = AccessToken.GetTokenCache(AppId, AppSecret);
jsapi_ticket = GetTicket(access_token);
System.Web.HttpContext.Current.Cache.Insert("jsapi_ticket", jsapi_ticket, null, DateTime.Now.AddSeconds(7200), TimeSpan.Zero);
}
//string access_token = AccessToken.GetTokenCache(AppId, AppSecret);
//jsapi_ticket = GetTicket(access_token);
//string url = System.Web.HttpContext.Current.Request.Url.AbsoluteUri.ToString();//当前的地址
string timestamp = WxPayApi.GenerateTimeStamp();//生成签名的时间戳
string nonceStr = WxPayApi.GenerateNonceStr();//生成签名的随机串
Dictionary<string, object> respDic = (Dictionary<string, object>)jss.DeserializeObject(jsapi_ticket);
jsapi_ticket = respDic["ticket"].ToString();//获取ticket
string[] ArrayList = { "jsapi_ticket=" + jsapi_ticket, "timestamp=" + timestamp, "noncestr=" + nonceStr, "url=" + reqUrl };
Array.Sort(ArrayList);
string signature = string.Join("&", ArrayList);
signature = FormsAuthentication.HashPasswordForStoringInConfigFile(signature, "SHA1").ToLower();
JsapiTicketInfo ticket = new JsapiTicketInfo();
ticket.appId = AppId;
ticket.timestamp = timestamp;
ticket.nonceStr = nonceStr;
ticket.signature = signature;
ticket.access_token = access_token;
ticket.jsapi_ticket = jsapi_ticket;
return ticket;
}
/// <summary>
/// 获取JsApi权限配置的数组/四个参数
/// </summary>
/// <returns></returns>
public static string GetJsApiString(string AppId, string AppSecret)
{
string timestamp = WxPayApi.GenerateTimeStamp();//生成签名的时间戳
string nonceStr = WxPayApi.GenerateNonceStr();//生成签名的随机串
string url = System.Web.HttpContext.Current.Request.Url.AbsoluteUri.ToString();//当前的地址
string jsapi_ticket = "";
//ticket 缓存7200秒
if (System.Web.HttpContext.Current.Cache["jsapi_ticket"] == null)
{
string access_token = AccessToken.GetTokenCache(AppId, AppSecret);
jsapi_ticket = GetTicket(access_token);
System.Web.HttpContext.Current.Cache.Insert("jsapi_ticket", jsapi_ticket, null, DateTime.Now.AddSeconds(7200), TimeSpan.Zero);
}
else
{
jsapi_ticket = System.Web.HttpContext.Current.Cache["jsapi_ticket"].ToString();
}
Dictionary<string, object> respDic = (Dictionary<string, object>)jss.DeserializeObject(jsapi_ticket);
jsapi_ticket = respDic["ticket"].ToString();//获取ticket
string[] ArrayList = { "jsapi_ticket=" + jsapi_ticket, "timestamp=" + timestamp, "noncestr=" + nonceStr, "url=" + url };
Array.Sort(ArrayList);
string signature = string.Join("&", ArrayList);
signature = FormsAuthentication.HashPasswordForStoringInConfigFile(signature, "SHA1").ToLower();
JsapiTicketInfo ticket = new JsapiTicketInfo();
ticket.appId = AppId;
ticket.timestamp = timestamp;
ticket.nonceStr = nonceStr;
ticket.signature = signature;
return jss.Serialize(ticket);
}
/// <summary>
/// 获取Ticket Json
/// </summary>
/// <returns>ticket对象</returns>
private static string GetTicket(string access_token)
{
string respText = "";
string url = string.Format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi", access_token);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream resStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(resStream, Encoding.Default);
respText = reader.ReadToEnd();
resStream.Close();
}
//Dictionary<string, object> respDic = (Dictionary<string, object>)jss.DeserializeObject(respText);
return respText;
}
}
}
JsapiTicketInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Model.Third.WeChat
{
/// <summary>
/// 微信Jssdk分享签名信息
/// </summary>
[Serializable]
public class JsapiTicketInfo
{
/// <summary>
/// 构造函数
/// </summary>
public JsapiTicketInfo()
{
//
//TODO: 在此处添加构造函数逻辑
//
}
/// <summary>
/// 必填,公众号的唯一标识
/// </summary>
public string appId { get; set; }
/// <summary>
/// 必填,生成签名的时间戳
/// </summary>
public string timestamp { get; set; }
/// <summary>
/// 必填,生成签名的随机串
/// </summary>
public string nonceStr { get; set; }
/// <summary>
/// 必填,签名
/// </summary>
public string signature { get; set; }
/// <summary>
/// access_token
/// </summary>
public string access_token { get; set; }
/// <summary>
/// jsapi_ticket
/// </summary>
public string jsapi_ticket { get; set; }
}
}
扩展方法
/**
* 生成时间戳,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数
* @return 时间戳
*/
public static string GenerateTimeStamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
/**
* 生成随机串,随机串包含字母或数字
* @return 随机串
*/
public static string GenerateNonceStr()
{
RandomGenerator randomGenerator = new RandomGenerator();
return randomGenerator.GetRandomUInt().ToString();
}
WebApi接口实现,这里可改成自己代码风格。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Data;
using Newtonsoft.Json.Linq;
namespace API.Controllers
{
/// <summary>
/// 微信分享模块API
/// </summary>
[RoutePrefix("Share")]
public class ShareController : ApiController
{
/// <summary>
/// 获取微信Jssdk分享签名信息的参数
/// </summary>
/// <returns></returns>
[Route("~/wx/jsapi/ticket"), HttpPost, AllowAnonymous]
public HttpResponseMessage GetTicket([FromBody] JObject obj)
{
ResultData result = new ResultData();
try
{
string shareUrl = obj["shareUrl"] != null ? obj["shareUrl"].ToString() : "";
if (string.IsNullOrWhiteSpace(shareUrl))
{
result.success = false;
result.return_code = HttpStatusCode.OK;
result.return_msg = "参数错误";
return Request.CreateResponse(HttpStatusCode.OK, result);
}
result.return_code = HttpStatusCode.OK;
result.return_msg = "请求成功";
result.success = true;
string AppID ="微信公众号APPID";
string AppSecret ="微信公众号SECRET";
result.data = JsapiTicket.GetObject(AppID, AppSecret, shareUrl);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
catch (Exception ex)
{
result.success = false;
result.return_code = HttpStatusCode.OK;
result.return_msg = "接口异常,请稍后再试!" + ex.Message;
return Request.CreateResponse(HttpStatusCode.OK, result);
}
}
}
}
mui h5
wx.share.js
/*
描述:微信浏览器,自定义分享
作者:LiKely
时间:2019-9-19 14:31:34
*/
/* 自定义类 */
var wx = wx || {};
wx.Share = function(shareParam, shareUrl) {
//当前URL
shareUrl = shareUrl ? shareUrl : window.location.href;
//获取签名信息
mui.ajax('https://你的api域名.com/wx/jsapi/ticket', {
type: 'post', //HTTP请求类型
dataType: 'json', //服务器返回json格式数据
timeout: 10000, //超时时间设置为10秒;
headers: {
'Content-Type': "application/x-www-form-urlencoded"
},
data: {
'shareUrl': shareUrl
},
success: function(res) {
//请求失败时的处理
if (!res.success) {
mui.toast(res.return_msg);
return false;
}
// 分享配置
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: res.data.appId, // 必填,企业号的唯一标识
timestamp: res.data.timestamp, // 必填,生成签名的时间戳
nonceStr: res.data.nonceStr, // 必填,生成签名的随机串
signature: res.data.signature, // 必填,签名,见附录1
jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo',
'onMenuShareQZone'
] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
wx.ready(function() {
//分享到朋友圈
wx.onMenuShareTimeline({
title: shareParam.title,
link: shareParam.link,
imgUrl: shareParam.imgUrl,
success: function() {
if (shareParam.successFn) {
shareParam.successFn();
}
},
cancel: function() {
if (shareParam.cancelFn) {
shareParam.cancelFn();
}
}
});
//分享给朋友
wx.onMenuShareAppMessage({
title: shareParam.title,
desc: shareParam.desc,
link: shareParam.link,
imgUrl: shareParam.imgUrl,
type: shareParam.type,
dataUrl: shareParam.dataUrl,
success: function() {
if (shareParam.successFn) {
shareParam.successFn();
}
},
cancel: function() {
if (shareParam.cancelFn) {
shareParam.cancelFn();
}
}
});
//分享到QQ
wx.onMenuShareQQ({
title: shareParam.title,
desc: shareParam.desc,
link: shareParam.link,
imgUrl: shareParam.imgUrl,
success: function() {
if (shareParam.successFn) {
shareParam.successFn();
}
},
cancel: function() {
if (shareParam.cancelFn) {
shareParam.cancelFn();
}
}
});
//分享到腾讯微博
wx.onMenuShareWeibo({
title: shareParam.title,
desc: shareParam.desc,
link: shareParam.link,
imgUrl: shareParam.imgUrl,
success: function() {
if (shareParam.successFn) {
shareParam.successFn();
}
},
cancel: function() {
if (shareParam.cancelFn) {
shareParam.cancelFn();
}
}
});
//分享到QQ空间
wx.onMenuShareQZone({
title: shareParam.title,
desc: shareParam.desc,
link: shareParam.link,
imgUrl: shareParam.imgUrl,
success: function() {
if (shareParam.successFn) {
shareParam.successFn();
}
},
cancel: function() {
if (shareParam.cancelFn) {
shareParam.cancelFn();
}
}
});
});
},
error: function(xhr, type, errorThrown) {}
});
}
h5.html 初始化调用js
<!DOCTYPE html>
<html lang="zh-Hans" xml:lang="zh-Hans" class="hairlines" style="font-size: 37.5px;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>微信H5自定义分享</title>
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
</head>
<body>
分享页面内容
</body>
<script type="text/javascript" src="js/mui.js?v=186522030"></script>
<script type="text/javascript" src="js/wx.share.js?v=186522030"></script>
<script type="text/javascript">
mui.ready(function() {
loadWxShare();
})
// 微信浏览器,自定义分享
function loadWxShare() {
var _self = this;
var shareUrl = window.location.href;
var shareParam = {
title: '', //分享标题
desc: '', //分享描述
link: 'http://xxxx.com', //分享链接,该链接域名必须与当前企业的可信域名一致
imgUrl: 'http://xxxxxxx/logo.png', //分享图标
type: 'link', //分享类型 music、 video或link, 不填默认为link
dataUrl: '', // 如果type是music或video, 则要提供数据链接, 默认为空
successFn: function() { // 用户确认分享后执行的回调函数
},
cancelFn: function() { // 用户取消分享后执行的回调函数
}
};
wx.Share(shareParam, shareUrl);
}
</script>
</html>
最后,移动端H5是无法直接调分享页面,这里只能放在onload初始加载,然后点击右上角三个点分享,这里只是配置分享的版面和内容,谨记!!! 另外,对于路由模式为hash的,路径中带有#号的需将#号前截取,然后自行拼接参数,在首页对带有参数的访问进行二次跳转,这里我琢磨了很久才想到的解决办法!!!
以上是关于uniapp中针对H5端做微信分享功能总结的主要内容,如果未能解决你的问题,请参考以下文章
uniapp h5+webapi 实现微信浏览器的自定义分享(微信JSSDK)
uniapp h5+webapi 实现微信浏览器的自定义分享(微信JSSDK)