一、首先了解本文要解决的问题:

公司前一段开发了移动网站,老板喜欢通过微信看,然后把看到的东西通过右上角的按钮分享出来,但老板发现分享出来的东西,没有指定的图片,没有描述;所以我就得老老实实干活了。。。

  如下图所示:

  

  点击发送给朋友,或者分享到朋友圈时,需要带上老板指定的图片、描述和标题。

二、尝试解决问题

  刚开始,通过网上查阅,发现微信会自动抓取页面的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版本的更多相关文章

  1. js微信禁用右上角的分享按钮,和vue中微信页面禁用右上角的分享按钮的问题

    1.隐藏微信网页右上角的按钮 document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() { // 通过下面这个 ...

  2. 用c#开发微信 (10) JS-SDK 基本用法- 分享接口“发送到朋友”

    微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包.通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统的能力,同时可以直接使用微信分享. ...

  3. Unity利用Share SDK实现QQ、微信及微博第三方登录及定制内容分享(附代码)

    最近因为公司的项目需要添加一些实用性的功能,需要添加第三方登录及分享,采用的是Mob的SDK,可以先到其官网下载对应的SDK 点击这里,为了方便后期进行数据统计和分析,所以可以先添加一个应用,添加成功 ...

  4. Windows 和 Linux下使用socket下载网页页面内容(可设置接收/发送超时)的代码

    主要难点在于设置recv()与send()的超时时间,具体要注意的事项,请看代码注释部分,下面是代码: #include <stdio.h> #include <sys/types. ...

  5. finecms设置伪静态后分享到微信不能访问怎么处理

    finecms设置伪静态后分享到微信不能访问,分享的链接自动增加了一串参数,类似这样的***.html?from=singlemessage&isappinstalled=0,刚开始ytkah ...

  6. php微信公众帐号发送红包

    开发框架为we7 所需参数:appid,appSecret,MchId,API密钥 <?php /** * 微信红包的类 * */ CLASS WXHongBao { private $mch_ ...

  7. C#开发微信门户及应用(19)-微信企业号的消息发送(文本、图片、文件、语音、视频、图文消息等)

    我们知道,企业号主要是面向企业需求而生的,因此内部消息的交流显得非常重要,而且发送.回复消息数量应该很可观,对于大企业尤其如此,因此可以结合企业号实现内部消息的交流.企业号具有关注安全.消息无限制等特 ...

  8. 用c#开发微信 (11) 微统计 - 阅读分享统计系统 1 基础架构搭建

    微信平台自带的统计功能太简单,有时我们需要统计有哪些微信个人用户阅读.分享了微信公众号的手机网页,以及微信个人用户访问手机网页的来源:朋友圈分享访问.好友分享消息访问等.本系统实现了手机网页阅读.分享 ...

  9. 用c#开发微信 (13) 微统计 - 阅读分享统计系统 3 UI设计及后台处理

      微信平台自带的统计功能太简单,有时我们需要统计有哪些微信个人用户阅读.分享了微信公众号的手机网页,以及微信个人用户访问手机网页的来源:朋友圈分享访问.好友分享消息访问等.本系统实现了手机网页阅读. ...

随机推荐

  1. js动态显示表格的汇总信息和详细信息

    我在做数据结果展示的时候,想要实现一个如下的功能:    用户可以选择一个时间段,默认显示这个时间段的汇总数据,当鼠标点击这个时间段的时候,将显示每个时间点的详细数据,再次点击的时候,详细数据收起,只 ...

  2. 关于 Servlet 和 Web

       文中也只是对Servlet和Web作简单的了解,有个初步的认识,深入的内容有待于进一步去研究. T. T _ . _ Servlet     Servlet(Server Applet),全称J ...

  3. $("").click与onclick的区别示例介绍

    Html代码: <script type="text/javascript"> $(function(){ $("#btn4").click(fun ...

  4. 去除utf8文件的bom标记

    http://stackoverflow.com/questions/1068650/using-awk-to-remove-the-byte-order-mark http://thegreyblo ...

  5. 关联查询 join on 和比较运算符 in

    join on多表之间的关联查询 写法select 字段 from 表1 t join 表2 s on t.字段1 = s.字段1 where 条件: 也可以这么写select 字段 from 表1 ...

  6. Apache运行python cgi程序

    Apache运行python cgi程序 环境 win10 x64 专业版 Apache2.4 python 2.7 Apache安装和配置 Apache服务器的安装请自行搜索.在Apache2.4中 ...

  7. 每天一命令 git checkout

    检出 checkout  是git常用命令之一.主要用于创建切换分支,覆盖本地修改等 git checkout 用于显示工作区,暂存区,版本库中文件的区别 git checkout -b branch ...

  8. 本机jdbc连接报The user specified as a definer ('root'@'%') does not exist

    昨晚一台测试服务器连接本机的mysql时,有些调用存储过程报"The user specified as a definer ('root'@'%') does not exist" ...

  9. Ionic 开发环境搭建

    android sdk环境搭建并非易事,本人经过无数失败,才使用以下方式成功 配置Ionic 开发环境 1.下载JDK并配置Java运行环境 http://www.oracle.com/technet ...

  10. HTML中表单提交数据GET、POST的区别

    表单提交数据Get和Post的区别: GET和POST是表单提交数据其中的两种方式,除此之外还有PUT.DELETE等. GET: GET的请求起因于正常的URL请求,或是没有指定METHOD的HTM ...