微信网站设置右上角发送、分享的内容——.net版本
一、首先了解本文要解决的问题:
公司前一段开发了移动网站,老板喜欢通过微信看,然后把看到的东西通过右上角的按钮分享出来,但老板发现分享出来的东西,没有指定的图片,没有描述;所以我就得老老实实干活了。。。
如下图所示:
点击发送给朋友,或者分享到朋友圈时,需要带上老板指定的图片、描述和标题。
二、尝试解决问题
刚开始,通过网上查阅,发现微信会自动抓取页面的title属性作为标题,和页面中第一张尺寸大于等于300*300的图片,作为分享出来的图片,于是带着偷懒的想法先这样尝试了一下,会有一下几个问题:
①不能自定义描述信息
②当页面内没有超过300*300的图片时,就不能显示图片了,于是我放了一张300*300的公司的logo在每个页面内,首先老板并不喜欢,其次会影响加载速度,同时当用户在隐藏图片还没加载出来的时候就进行分享动作,那么图片还是识别不出来。。。
改完第一次,用了一段时间,老板不满意,要求继续优化,于是第二版开始更新。。
既然不能走野路子,只能通过微信给出的开发文档进行更改了。。请参考官网文档:http://mp.weixin.qq.com/wiki/7/1c97470084b73f8e224fe6d9bab1625b.html
微信发布了《微信JS-SDK说明文档》供开发者使用,并且给出了示例,包含了php、java、nodejs、python示例,然而并没有什么卵用!因为我是一个.net开发!!!
只能自己动手,丰衣足食了。
三、说干就干
代码分两个部分,js和后端;后端我们目前使用的是webservice,其中用到了Cache,下面贴主要代码了
①接口中代码,需要解决js跨域问题
[WebMethod(Description = "微信分享请求参数接口")]
[ScriptMethod(UseHttpGet = false)]
public string GetWXSharedParam(string url)
{
string timestamp = Common.APPApplyClass.WxSharedClass.ConvertDateTimeInt(DateTime.Now).ToString();
string nonceStr = Guid.NewGuid().ToString();
string ticket = string.Empty;
string appId = ConfigurationManager.AppSettings["appid"]; //获取jsapi_ticket
if (HttpRuntime.Cache["JsApiTicket"] == null)
{
Common.APPApplyClass.WxSharedClass.GetJsApiTicket();
}
ticket = HttpRuntime.Cache["JsApiTicket"] as string;
if (string.IsNullOrEmpty(ticket))
{
return JsonConvert.SerializeObject(new { result = false });
} SortedList<string, string> SLString = new SortedList<string, string>();
SLString.Add("noncestr", nonceStr);
SLString.Add("url", url);
SLString.Add("timestamp", timestamp);
SLString.Add("jsapi_ticket", ticket); StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> des in SLString) //返回的是KeyValuePair,在学习的时候尽量少用var,起码要知道返回的是什么
{
sb.Append(des.Key + "=" + des.Value + "&");
}
string signature = sb.ToString().Substring(, sb.ToString().Length - );
signature = FormsAuthentication.HashPasswordForStoringInConfigFile(signature, "SHA1").ToLower(); return JsonConvert.SerializeObject(new { result = true, timestamp, nonceStr, signature, appId });
}
②新建了一个类,提供了上个方法中需要调用的方法和实体
public static class WxSharedClass
{
static System.Web.Caching.Cache objCache = HttpRuntime.Cache; /// <summary>
/// 获取jsapi_ticket
/// 有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket
/// </summary>
/// <returns></returns>
public static void GetJsApiTicket()
{
string accessToken = string.Empty;
if (objCache["AccessToken"] == null)
{
GetAccessToken();
}
accessToken = objCache["AccessToken"] as string;
if (!string.IsNullOrEmpty(accessToken))
{
accessToken = objCache["AccessToken"] as string;
string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken + "&type=jsapi";
string resStr = HttpGet(url);
TicketModel model = JsonConvert.DeserializeObject<TicketModel>(resStr);
if (!string.IsNullOrEmpty(model.ticket))
{
//请求成功了
DateTime dt = DateTime.Now.AddSeconds(Convert.ToInt32(model.expires_in));
objCache.Insert("JsApiTicket", model.ticket, null, dt, System.Web.Caching.Cache.NoSlidingExpiration);
}
}
} /// <summary>
/// DateTime时间格式转换为Unix时间戳格式
/// </summary>
/// <param name="time"> DateTime时间格式</param>
/// <returns>Unix时间戳格式</returns>
public static int ConvertDateTimeInt(System.DateTime time)
{
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(, , ));
return (int)(time - startTime).TotalSeconds;
} /// <summary>
/// 获取access_token
/// 有效期7200秒,开发者必须在自己的服务全局缓存access_token
/// </summary>
/// <returns></returns>
private static void GetAccessToken()
{
string appId = ConfigurationManager.AppSettings["appid"];//订阅号应用id
string secret = ConfigurationManager.AppSettings["secret"];//订阅号应用密钥
string url =
"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + secret;
string resStr = HttpGet(url);
if (!resStr.Contains("errcode"))//string.IsNullOrEmpty(model.errcode)
{
//请求成功了
AccessTokenModel model = JsonConvert.DeserializeObject<AccessTokenModel>(resStr);
DateTime dt = DateTime.Now.AddSeconds(Convert.ToInt32(model.expires_in));
objCache.Insert("AccessToken", model.access_token, null, dt, System.Web.Caching.Cache.NoSlidingExpiration);
}
} /// <summary>
/// HttpGet请求
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
private static string HttpGet(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
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.GetEncoding("utf-8"));
string retString = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close();
return retString;
}
} public class AccessTokenModel
{
public string access_token; public string expires_in;
} public class TicketModel
{
public string errcode; public string errmsg; public string ticket; public string expires_in;
}
③js代码
//引用jquery
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript">
var title = '测试标题',
imgUrl = '图片地址',
desc = '测试描述'; $(function () {
/*
wx.checkJsApi({
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage'
], // 需要检测的JS接口列表,所有JS接口列表见附录2,
success: function (res) {
allPrpos(res);
// 以键值对的形式返回,可用的api值true,不可用为false
// 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
}
});
*/ var param = {
url: location.href.split('#')[0]
};
//从后端请求参数
AjaxPostData("url", param, function (json) {
if (json.result === true) { wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: json.appId, // 必填,公众号的唯一标识
timestamp: json.timestamp, // 必填,生成签名的时间戳
nonceStr: json.nonceStr, // 必填,生成签名的随机串
signature: json.signature,// 必填,签名,见附录1
menuItem: 'addContact',
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage'
] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
}
});
}); wx.ready(function () {
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。 //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口
wx.onMenuShareTimeline({
title: title, // 分享标题
link: window.location.href, // 分享链接
imgUrl: imgUrl, // 分享图标
trigger: function (res) {
//监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。
//不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回。
},
success: function (res) {
//接口调用成功时执行的回调函数。
},
cancel: function (res) {
//用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。
},
fail: function (res) {
//接口调用失败时执行的回调函数。
},
complete: function (res) {
//接口调用完成时执行的回调函数,无论成功或失败都会执行。
}
//以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下:
/*调用成功时:"xxx:ok" ,其中xxx为调用的接口名
用户取消时:"xxx:cancel",其中xxx为调用的接口名
调用失败时:其值为具体错误信息
*/
}); //获取“分享给朋友”按钮点击状态及自定义分享内容接口
wx.onMenuShareAppMessage({
title: title, // 分享标题
desc: desc, // 分享描述
link: window.location.href, // 分享链接
imgUrl: imgUrl, // 分享图标
type: 'link', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
}); wx.error(function (res) {
//allPrpos(res);
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 }); //这是我抄的我们前端开发小组的,不知道他们抄的谁的。。。
var AjaxPostData = function(url, data, success) {
/// <summary>
/// Ajax的POST方法
/// </summary>
/// <param name="url" type="String">
/// 网址/参数
/// </param>
/// <param name="data" type="JSON类型">
/// 参数
/// </param>
/// <param name="success" type="Function">
/// 回调函数,不用这个的时候为同步,用的时候为异步(有一个返回数据参数(数据))
/// </param>
/// <returns type="string">同步时返回数据,异步时在回调函数中取</returns> var val = ""; var param = {
url: encodeURI(url),
type: "POST",
timeout: 50000,
async: false,
data: data,
dataType: "text",
success: function(tempData) {},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log(arguments);
}
}; if (!success) {
param.async = false;
param.success = function(tempData) {
val = tempData;
};
} else {
param.async = true;
param.success = function(r) {
if (success) {
// var result = $(r).find('string').html();
// result = result.StringToJsonObject(); var len = r.length;
var result = JSON.parse(r.substring(76, len - 9)); success(result);
}
};
} $.ajax(param); return val;
}
</script>
微信网站设置右上角发送、分享的内容——.net版本的更多相关文章
- js微信禁用右上角的分享按钮,和vue中微信页面禁用右上角的分享按钮的问题
1.隐藏微信网页右上角的按钮 document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() { // 通过下面这个 ...
- 用c#开发微信 (10) JS-SDK 基本用法- 分享接口“发送到朋友”
微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包.通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统的能力,同时可以直接使用微信分享. ...
- Unity利用Share SDK实现QQ、微信及微博第三方登录及定制内容分享(附代码)
最近因为公司的项目需要添加一些实用性的功能,需要添加第三方登录及分享,采用的是Mob的SDK,可以先到其官网下载对应的SDK 点击这里,为了方便后期进行数据统计和分析,所以可以先添加一个应用,添加成功 ...
- Windows 和 Linux下使用socket下载网页页面内容(可设置接收/发送超时)的代码
主要难点在于设置recv()与send()的超时时间,具体要注意的事项,请看代码注释部分,下面是代码: #include <stdio.h> #include <sys/types. ...
- finecms设置伪静态后分享到微信不能访问怎么处理
finecms设置伪静态后分享到微信不能访问,分享的链接自动增加了一串参数,类似这样的***.html?from=singlemessage&isappinstalled=0,刚开始ytkah ...
- php微信公众帐号发送红包
开发框架为we7 所需参数:appid,appSecret,MchId,API密钥 <?php /** * 微信红包的类 * */ CLASS WXHongBao { private $mch_ ...
- C#开发微信门户及应用(19)-微信企业号的消息发送(文本、图片、文件、语音、视频、图文消息等)
我们知道,企业号主要是面向企业需求而生的,因此内部消息的交流显得非常重要,而且发送.回复消息数量应该很可观,对于大企业尤其如此,因此可以结合企业号实现内部消息的交流.企业号具有关注安全.消息无限制等特 ...
- 用c#开发微信 (11) 微统计 - 阅读分享统计系统 1 基础架构搭建
微信平台自带的统计功能太简单,有时我们需要统计有哪些微信个人用户阅读.分享了微信公众号的手机网页,以及微信个人用户访问手机网页的来源:朋友圈分享访问.好友分享消息访问等.本系统实现了手机网页阅读.分享 ...
- 用c#开发微信 (13) 微统计 - 阅读分享统计系统 3 UI设计及后台处理
微信平台自带的统计功能太简单,有时我们需要统计有哪些微信个人用户阅读.分享了微信公众号的手机网页,以及微信个人用户访问手机网页的来源:朋友圈分享访问.好友分享消息访问等.本系统实现了手机网页阅读. ...
随机推荐
- C#编程总结(一)序列化
C#编程总结(一)序列化 序列化是将对象状态转换为可保持或传输的格式的过程.与序列化相对的是反序列化,它将流转换为对象.这两个过程结合起来,可以轻松地存储和传输数据. 几种序列化技术: 1) ...
- iOS阶段学习第21天笔记(ARC内存管理-Copy-代理)
iOS学习(OC语言)知识点整理 一.OC 中的ARC内存管理 1)ARC中释放对象的内存原则:看这个对象有没有强引用指向它 2)strong:强引用,默认情况下的引用都是强引用 3) weak:弱引 ...
- 数据库SQL server规则的创建、查看、修改和规则的绑定与松绑、删除
用CREATE RULE语句创建规则 创建雇佣日期规则 hire_date_rule CREATE RULE hire_date_rule AS @hire_date>='1980-01-01' ...
- 转:python signal信号
转自:http://www.jb51.net/article/74844.htm 在liunx系统中要想每隔一分钟执行一个命令,最普遍的方法就是crontab了,如果不想使用crontab,经同事指点 ...
- Scalaz(11)- Monad:你存在的意义
前面提到了scalaz是个函数式编程(FP)工具库.它提供了许多新的数据类型.拓展的标准类型及完整的一套typeclass来支持scala语言的函数式编程模式.我们知道:对于任何类型,我们只需要实现这 ...
- 理解 OpenStack 高可用(HA) (4): Pacemaker 和 OpenStack Resource Agent (RA)
本系列会分析OpenStack 的高可用性(HA)概念和解决方案: (1)OpenStack 高可用方案概述 (2)Neutron L3 Agent HA - VRRP (虚拟路由冗余协议) (3)N ...
- ubuntu 安装配置ssh
1.安装ssh-server sudo apt-get install openssh-server 2.设置管理员密码访问 sudo vim /etc/ssh/sshd_config 将“Permi ...
- [.NET] 使用Json.NET提供依赖注入功能(Dependence Injection)
[.NET] 使用Json.NET提供依赖注入功能(Dependence Injection) 前言 在一些小型项目的开发情景里,系统不需要大型DI Framework所提供的:单一对象生成.生命周期 ...
- WindowsForm如何实现类似微软project软件的甘特图?
在管理软件研发过程中,特别是涉及项目管理或者生产计划方面,都需要一款类似微软project的控件对项目下的分解任务进行图形展示(甘特图).下面介绍一下在WindowsForm下如何实现类似微软proj ...
- 实用技巧:使用 jQuery 异步加载 JavaScript 脚本
JavaScript 加载器在 Web 开发中是非常强大和有用的工具.目前流行的几个加载器,像 curljs.LABjs 和 RequireJS 使用都很广泛.他们功能强大的,但有些情况下可以有更简单 ...