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

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

  如下图所示:

  

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

二、尝试解决问题

  刚开始,通过网上查阅,发现微信会自动抓取页面的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>

最新文章

  1. caffe中的props
  2. mysql乱码解决
  3. SQL语法中的子查询Subqueries
  4. GLSL语言基础
  5. Navicat提示Access violation at address 004E9844 in module ‘navicat.exe’
  6. c语言中argc和argv是什么意思?
  7. Class TBoundlabel not found and so on..
  8. jqTransform——学习(1)
  9. IE8下div中2个button仅仅显示一个
  10. 实际开发---&gt;php时间函数
  11. Get started with Google Analytics
  12. Microsoft Visual Studio 2012旗舰版(VS2012中文版下载)官方中文版
  13. 1-1 maven 学习笔记(1-6章)
  14. day1:java学习第一天之eclipse安装
  15. echart的x换行
  16. 阿里云 配置ssl 在nginx上
  17. [计算机视觉] 图像拼接 Image Stitching
  18. UITableView 的常用可复制代码
  19. Python零碎(一)
  20. easygui.py的安装和下载地址

热门文章

  1. TextBox禁止复制粘贴和数字验证,小数验证,汉字验证
  2. MVC-自定义HttpModule处理
  3. 《第一行代码》学习笔记——第1章 开始启程,你的第一行Android代码
  4. php中数组遍历改值
  5. Discuz X2任务开发
  6. 分布式环境下rabbitmq发布与订阅端
  7. ENVI【遥感图像预处理之图像的几何校正】
  8. javascript适合移动端的响应式瀑布流插件实例演示
  9. jquery.sobox 经典版弹窗控件
  10. jQuery Wheel Menu:实现漂亮的 Path 风格旋转菜单