要实现微信分享网页时自定义缩略图和简介,需开发者在公众平台网站中创建公众号、获取接口权限后,通过微信JS-SDK的分享接口,来实现微信分享功能。

下面来说明实现步骤。

第一部分 准备步骤

步骤一:注册微信公众号。

申请公众号网址

步骤二:认证微信公众号。

通过左侧导航“设置”--“微信认证”进入。不进行认证,无法使用微信JS-SDK分享接口。详见接口权限说明文档

开通微信认证需准备如下图所示材料,具体认证流程详见微信认证申请流程(企业类型)文档

步骤三:设置IP白名单。获取AppID和AppSecret。

通过左侧导航“开发”--“基本配置”进入。通过开发者ID及密码调用获取access_token接口时,需要设置访问来源IP为白名单。可将服务器ip、开发机ip、测试机ip都进行设置。

步骤四:配置JS接口安全域名。

通过左侧导航“设置”--“公众号设置”--“功能设置”进入。设置JS接口安全域名后,公众号开发者才可在该域名下调用微信开放的JS接口。具体设置步骤如下图所示。

步骤五:填写服务器配置。(可选)

通过左侧导航“开发”--“基本配置”进入。仅仅是为了实现分享功能的话,不是必填项,但为了实现其他功能(如回复消息),需进行配置。服务器配置是为了正确响应微信发送的Token验证等信息。详见入门指引文档中“1.4开发者基本配置”部分。

第二部分 开发步骤

步骤1:通过公众号里的AppID和AppSecret获取access_token(接口调用凭据),并进行缓存(有效期为2小时)

公众平台以access_token为接口调用凭据,来调用接口,所有接口的调用需要先获取access_token,access_token在2小时内有效,过期需要重新获取,但1天内获取次数有限,开发者需自行存储,详见获取接口调用凭据(access_token)文档

public static string GetAccess_token()
{
string access_token = string.Empty;
//从缓存获取
string cacheName = "Weixin_access_token";
object obj = CacheHelper.GetCache(cacheName);
if (obj != null)
{
access_token = obj.ToString();
}
//从接口获取
else
{
string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + AppID + "&secret=" + AppSecret;
access_token = SubmitHttpWebRequest(url, "access_token");
//设置缓存
//7200秒内有效,不可无限次调取微信接口
CacheHelper.SetCache(cacheName, access_token, );
}
return access_token;
}

 步骤2:获取jsapi_ticket,并进行缓存(有效期为2小时)。jsapi_ticket是公众号用于调用微信JS接口的临时票据

public static string GetJsapi_Ticket()
{
string jsapi_ticket = string.Empty;
//从缓存获取
string cacheName = "Weixin_jsapi_ticket";
object obj = CacheHelper.GetCache(cacheName);
if (obj != null)
{
jsapi_ticket = obj.ToString();
}
//从接口获取
else
{
string access_token = GetAccess_token();
string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=" + access_token;
jsapi_ticket = SubmitHttpWebRequest(url, "ticket");
//设置缓存
//7200秒内有效,不可无限次调取微信接口
CacheHelper.SetCache(cacheName, jsapi_ticket, );
}
return jsapi_ticket;
}

步骤3:生成JS-SDK权限验证的签名信息,并通过接口调用

签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。

public static string[] GetSignature(string url)
{
//JSAPI调用凭证
string jsapi_ticket = GetJsapi_Ticket(); //随机生成的字符串
string noncestr = CreateRandCode(); //当前时间戳
TimeSpan ts = DateTime.Now - new DateTime(, , , , , , );
string timestamp = ((Int64)ts.TotalSeconds).ToString();
//string timestamp = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();//.net framework4.6 //url
if (url.IndexOf("#") > )
{
url = url.Substring(, url.IndexOf("#"));
} //签名
StringBuilder string1 = new StringBuilder();
string1.AppendFormat("jsapi_ticket={0}&noncestr={1}&timestamp={2}&url={3}", jsapi_ticket, noncestr, timestamp, url);
string signature = GetSHA1(string1.ToString()); //返回相关信息
string[] rtn = new string[] { AppID, noncestr, timestamp, signature };
return rtn;
}

通过接口调用(公众平台接口调用仅支持80端口。)

public class WeixinController : ApiController
{
/// <summary>
/// 获取签名信息
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
[HttpGet]
[AllowAnonymous]
public WeixinSignatureConfig GetSignature(string url)
{
//微信配置
string[] weixin = Tencent.WeixinConfig.GetSignature(url);
WeixinSignatureConfig weixinConfig = new WeixinSignatureConfig
{
appId = weixin[],
nonceStr = weixin[],
timestamp = weixin[],
signature = weixin[]
};
return weixinConfig;
}
}

相关方法:

提交网络请求 SubmitHttpWebRequest(string url, string para = "")

private static string SubmitHttpWebRequest(string url, string para = "")
{
string retString = string.Empty; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.ContentType = "application/json";
request.Timeout = ;
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string encoding = response.ContentEncoding;
if (encoding == null || encoding.Length < )
{
encoding = "UTF-8"; //默认编码
}
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding)))
{
retString = reader.ReadToEnd(); if (para != "")
{
JObject jsonObj = (JObject)JsonConvert.DeserializeObject(retString);
if (jsonObj[para] != null)
{
retString = jsonObj[para].ToString();
}
}
}
}
catch (WebException ex)
{
retString = null;
}
return retString;
}

生成随机字符串CreateRandCode(int codeLen = 16)

public static string CreateRandCode(int codeLen = )
{
string codeSerial = "2,3,4,5,6,7,a,c,d,e,f,h,i,j,k,m,n,p,r,s,t,A,C,D,E,F,G,H,J,K,M,N,P,Q,R,S,U,V,W,X,Y,Z";
if (codeLen == )
{
codeLen = ;
}
string[] arr = codeSerial.Split(',');
string code = "";
int randValue = -;
Random rand = new Random(unchecked((int)DateTime.Now.Ticks));
for (int i = ; i < codeLen; i++)
{
randValue = rand.Next(, arr.Length - );
code += arr[randValue];
}
return code;
}

SHA1加密GetSHA1(string string1)

private static string GetSHA1(string string1)
{
SHA1 sha;
ASCIIEncoding enc;
string hash = "";
sha = new SHA1CryptoServiceProvider();
enc = new ASCIIEncoding();
byte[] dataToHash = enc.GetBytes(string1);
byte[] dataHashed = sha.ComputeHash(dataToHash);
hash = BitConverter.ToString(dataHashed).Replace("-", "");
hash = hash.ToLower();
return hash;
}

缓存设置CacheHelper.cs

using System;
using System.Collections;
using System.Web;
using System.Web.Caching; namespace WeixinShare
{
/// <summary>
/// Caching 的摘要说明
/// </summary>
public class CacheHelper
{
/// <summary>
/// 获取当前应用程序指定CacheKey的Cache值
/// </summary>
/// <param name="CacheKey">
/// <returns></returns>y
public static object GetCache(string CacheKey)
{
System.Web.Caching.Cache objCache = HttpRuntime.Cache;
return objCache[CacheKey];
} /// <summary>
/// 设置当前应用程序指定CacheKey的Cache值
/// </summary>
/// <param name="CacheKey">
/// <param name="objObject">
public static void SetCache(string CacheKey, object objObject)
{
System.Web.Caching.Cache objCache = HttpRuntime.Cache;
objCache.Insert(CacheKey, objObject);
} /// <summary>
/// 设置当前应用程序指定CacheKey的Cache值
/// </summary>
/// <param name="CacheKey">
/// <param name="objObject">
public static void SetCache(string CacheKey, object objObject, DateTime absoluteExpiration, TimeSpan slidingExpiration)
{
System.Web.Caching.Cache objCache = HttpRuntime.Cache;
objCache.Insert(CacheKey, objObject, null, absoluteExpiration, slidingExpiration);
} /// <summary>
/// 设置数据缓存
/// </summary>
public static void SetCache(string CacheKey, object objObject, int timeout = )
{
try
{
if (objObject == null) return;
var objCache = HttpRuntime.Cache;
//相对过期
//objCache.Insert(cacheKey, objObject, null, DateTime.MaxValue, timeout, CacheItemPriority.NotRemovable, null);
//绝对过期时间
objCache.Insert(CacheKey, objObject, null, DateTime.Now.AddSeconds(timeout), TimeSpan.Zero, CacheItemPriority.High, null);
}
catch (Exception)
{
//throw;
}
} /// <summary>
/// 清除单一键缓存
/// </summary>
/// <param name="key">
public static void RemoveKeyCache(string CacheKey)
{
try
{
System.Web.Caching.Cache objCache = HttpRuntime.Cache;
objCache.Remove(CacheKey);
}
catch { }
} ///// <summary>
///// 清除所有缓存
///// </summary>
//public static void RemoveAllCache()
//{
// System.Web.Caching.Cache _cache = HttpRuntime.Cache;
// IDictionaryEnumerator CacheEnum = _cache.GetEnumerator();
// if (_cache.Count > 0)
// {
// ArrayList al = new ArrayList();
// while (CacheEnum.MoveNext())
// {
// al.Add(CacheEnum.Key);
// }
// foreach (string key in al)
// {
// _cache.Remove(key);
// }
// }
//} /// <summary>
/// 清除所有缓存
/// </summary>
public static void RemoveAllCache()
{
var cache = HttpRuntime.Cache;
var cacheEnum = cache.GetEnumerator();
while (cacheEnum.MoveNext())
{
cache.Remove(cacheEnum.Key.ToString());
}
} /// <summary>
/// 以列表形式返回已存在的所有缓存
/// </summary>
/// <returns></returns>
public static ArrayList ShowAllCache()
{
ArrayList al = new ArrayList();
System.Web.Caching.Cache _cache = HttpRuntime.Cache;
if (_cache.Count > )
{
IDictionaryEnumerator CacheEnum = _cache.GetEnumerator();
while (CacheEnum.MoveNext())
{
al.Add(CacheEnum.Key);
}
}
return al;
}
}
}

Models,WeixinSignatureConfig

namespace WeixinShare.Models
{
public class WeixinSignatureConfig
{
public string appId { get; set; }
public string nonceStr { get; set; }
public string timestamp { get; set; }
public string signature { get; set; }
}
}

步骤4:网页前端调用微信JSSDK

微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。

通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。

@*微信分享接口*@
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
<script src="~/Scripts/WeixinShare.js"></script>
<script type="text/javascript">
//分享标题
var title = '微信分享页标题';
//分享描述
var desc = '微信分享页描述';
//分享链接
var link = window.location.href;
//分享缩略图
var imgUrl = link.substring(0, link.indexOf(window.location.pathname)) + '/Content/logo.png';
//分享设置
WeixinShare(title, desc, link, imgUrl);
</script>

方法封装:WeixinShare.js

function WeixinShare(title, desc, link, imgUrl, jsApiList) {
$(document).ready(function () {
//分享链接处理
if (link.indexOf("#") > 0) {
link = link.substring(0, link.indexOf("#"));
}
//通过Ajax获取签名信息,不影响主页面的加载逻辑
$.ajax({
url: "/apiaction/Weixin/GetSignature",
data: "url=" + encodeURIComponent(link),
type: "GET",
dataType: "json",
success: function (data) {
//注入配置信息
wx.config({
debug: false,// 开启调试模式,调用的所有api的返回值会在客户端alert出来
appId: data.appId,// 必填,公众号的唯一标识
timestamp: parseInt(data.timestamp),// 必填,生成签名的时间戳
nonceStr: data.nonceStr,// 必填,生成签名的随机串
signature: data.signature,// 必填,签名
jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData']// 必填,需要使用的JS接口列表
}); //config验证成功后调用微信接口
wx.ready(function () {
//分享给朋友
wx.updateAppMessageShareData({
title: title, desc: desc, link: link, imgUrl: imgUrl,
success: function () { }
});
//分享到朋友圈
wx.updateTimelineShareData({
title: title, desc: desc, link: link, imgUrl: imgUrl,
success: function () { }
});
});
wx.error(function (res) {
console.log(res);
});
}
});
});
}

完整代码下载:

https://github.com/coolxiaoyi/WeixinShare-JSSDK

总结:

虽然是很简单的一个分享功能,但是步骤较多,涉及到公众号注册、认证、ip配置、域名配置,和获取凭证access_token、jsapi_ticket、SHA1加密算法、config验证等,再加上微信开发文档不够明了,所以大家在开发时会有各种困扰。现在将实现步骤整理出来,希望这篇文章能帮助到大家!

微信分享网页时自定义缩略图和简介(.net版本)的更多相关文章

  1. html静态页面实现微信分享思路

    微信分享网页的时候,希望分享出来的链接是标题+描述+缩略图,微信开发代码示例里已提供了方法,但只适用于动态页面.由于dedecms是生成了静态文件,其实我想使用ajax获取jssdk参数也能也能实现微 ...

  2. cocos2d-x C++ (Android)集成第三方微信分享

    ShareSDK Android for cocos2d-x 此文档为ShareSDK Android for cocos3.x的版本,如您集成的是2.X的版本文档请到这里:cocos2.x集成文档 ...

  3. Android 微信分享解疑

    from:http://blog.csdn.net/freesonhp/article/details/10756663 1.建立自己的应用 TestShareWX (1)应用包名是com.frees ...

  4. React Native 微信分享闪退的解决办法

    Android中编写微信分享功能时出现了闪退的现象,经过几番资料的查找,发现是应用签名的问题,解决办法如下: 1.    进入微信官网的开放平台--->资源中心---->资源下载----& ...

  5. dedecms织梦文章微信分享带缩略图与简介

    dedecms V5.7二次开发 php5.6 mysql5.1 问题:dedecms文章分享到微信,带缩略图与简介.如下图: 1.准备工作 PHP 5.3+ 并且 curl扩展已经开启 微信服务号一 ...

  6. Android调试大法 自定义IDE默认签名文件==>微信支付、微信登录、微信分享,debug时调试通过,release时调不起微信

    转载地址:http://blog.yanzhenjie.com Android调试大法之自定义IDE默认签名文件,你是否为调试第三方SDK时debug签名和release签名发生冲突而烦恼?你是否在d ...

  7. .Net微信网页开发之使用微信JS-SDK自定义微信分享内容

    第一步.微信JS-SDK的使用步骤,配置信息的生成获取讲解: 关于JS-SDK的使用步骤和timestamp(时间戳),nonceStr(随机串),signature(签名),access_token ...

  8. 微信内 H5 页面自定义分享

    起源: 最近公司在做一个活动的h5页面,在微信内打开时需要进行微信授权,然后后端会重定向到这个页面并且携带了一些参数(openid等).问题是点击微信的原生分享时,会把携带的这些参数一起分享出去,等于 ...

  9. 微信分享自定义图片标题摘要-微信官方API

    我们平时在使用微信内置浏览器打开网页想要分享给好友或者发到朋友圈的时候经常会遇到这样的问题, 别人的网页分享的时候是这样的: 而我们自己的网页分享后这这样的: 看到有人说不做任何设置,微信分享时会自动 ...

随机推荐

  1. python基础(24):面向对象三大特性一(继承)

    1. 继承 1.1 什么是继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类. python中类的继承分为:单继承和多继 ...

  2. CSS语法规范一

    CSS语法规范 CSS规则由两个主要的部分构成:选择器以及一条或多条声明. p{ color: red; font-size: 12px; } CSS代码风格 样式格式书写 紧凑格式 h3 {colo ...

  3. xml解析-jaxp删除结点

    jaxp删除结点 / 删除sex结点 * 1.创建解析器工厂 * 2.根据解析器工厂创建解析器 * 3.解析xml返回document * * 4.得到sex结点 * 5.得到sex的父节点 getP ...

  4. 「SAP技术」SAP MM 事务代码ME17的用法

    SAP MM 事务代码ME17的用法 1,如下采购信息记录需要被归档: PIR号码,5300007816   2, ME12打上删除标记,   3, 事务代码ME17做归档 3.1 创建archive ...

  5. 剑指offer 19:二叉树的镜像

    题目描述 操作给定的二叉树,将其变换为源二叉树的镜像.   输入描述:   解题思路 这一问题明显,在进行递归遍历节点时,将根节点的左右子树进行交换,因此完成树的遍历即可.   C++实现代码 /* ...

  6. Django和前端用ajax传输json等数据

    需要传输的是下图中所有的input中客户端设置的数据 整个页面是用js生成,代码不长,但是用了许多拼接,看起来开比较乱,页面的核心就是下面的部分,有一些关键参数部分就不放了,可以跳过这个 下面开始重点 ...

  7. Django框架(二十四)-- Django rest_framework-路由控制与响应器

    一.路由控制 # 1.基本路由: url(r'^publish/$', views.PublishView.as_view()), # 2.半自动路径:views.PublishView.as_vie ...

  8. JSAPI签权

    JSAPI鉴权----钉钉H5开发 虽钉钉开发文档上写着不需要JSAPI签权,但这仅仅是针对Android手机 所以为了保险起见,在使用JSAPI前,都需要签权. 否则:dd.ready({}) 将不 ...

  9. 使用Azure进行自动化机器学习

    什么是自动化机器学习? 自动化的机器学习,也称为 AutoML,让数据科研人员. 分析人员和开发人员,同时维护模型质量构建具有高缩放性. 效率和工作效率的机器学习模型. 自动化机器学习生成的机器学习模 ...

  10. 简单web服务工作流程梳理

       一.用户访问web基本流转过程梳理 二.web框架粗略概括