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

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

  如下图所示:

  

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

二、尝试解决问题

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

  1. [WebMethod(Description = "微信分享请求参数接口")]
  2. [ScriptMethod(UseHttpGet = false)]
  3. public string GetWXSharedParam(string url)
  4. {
  5. string timestamp = Common.APPApplyClass.WxSharedClass.ConvertDateTimeInt(DateTime.Now).ToString();
  6. string nonceStr = Guid.NewGuid().ToString();
  7. string ticket = string.Empty;
  8. string appId = ConfigurationManager.AppSettings["appid"];
  9.  
  10. //获取jsapi_ticket
  11. if (HttpRuntime.Cache["JsApiTicket"] == null)
  12. {
  13. Common.APPApplyClass.WxSharedClass.GetJsApiTicket();
  14. }
  15. ticket = HttpRuntime.Cache["JsApiTicket"] as string;
  16. if (string.IsNullOrEmpty(ticket))
  17. {
  18. return JsonConvert.SerializeObject(new { result = false });
  19. }
  20.  
  21. SortedList<string, string> SLString = new SortedList<string, string>();
  22. SLString.Add("noncestr", nonceStr);
  23. SLString.Add("url", url);
  24. SLString.Add("timestamp", timestamp);
  25. SLString.Add("jsapi_ticket", ticket);
  26.  
  27. StringBuilder sb = new StringBuilder();
  28. foreach (KeyValuePair<string, string> des in SLString) //返回的是KeyValuePair,在学习的时候尽量少用var,起码要知道返回的是什么
  29. {
  30. sb.Append(des.Key + "=" + des.Value + "&");
  31. }
  32. string signature = sb.ToString().Substring(, sb.ToString().Length - );
  33. signature = FormsAuthentication.HashPasswordForStoringInConfigFile(signature, "SHA1").ToLower();
  34.  
  35. return JsonConvert.SerializeObject(new { result = true, timestamp, nonceStr, signature, appId });
  36. }

  ②新建了一个类,提供了上个方法中需要调用的方法和实体

  1. public static class WxSharedClass
  2. {
  3. static System.Web.Caching.Cache objCache = HttpRuntime.Cache;
  4.  
  5. /// <summary>
  6. /// 获取jsapi_ticket
  7. /// 有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket
  8. /// </summary>
  9. /// <returns></returns>
  10. public static void GetJsApiTicket()
  11. {
  12. string accessToken = string.Empty;
  13. if (objCache["AccessToken"] == null)
  14. {
  15. GetAccessToken();
  16. }
  17. accessToken = objCache["AccessToken"] as string;
  18. if (!string.IsNullOrEmpty(accessToken))
  19. {
  20. accessToken = objCache["AccessToken"] as string;
  21. string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken + "&type=jsapi";
  22. string resStr = HttpGet(url);
  23. TicketModel model = JsonConvert.DeserializeObject<TicketModel>(resStr);
  24. if (!string.IsNullOrEmpty(model.ticket))
  25. {
  26. //请求成功了
  27. DateTime dt = DateTime.Now.AddSeconds(Convert.ToInt32(model.expires_in));
  28. objCache.Insert("JsApiTicket", model.ticket, null, dt, System.Web.Caching.Cache.NoSlidingExpiration);
  29. }
  30. }
  31. }
  32.  
  33. /// <summary>
  34. /// DateTime时间格式转换为Unix时间戳格式
  35. /// </summary>
  36. /// <param name="time"> DateTime时间格式</param>
  37. /// <returns>Unix时间戳格式</returns>
  38. public static int ConvertDateTimeInt(System.DateTime time)
  39. {
  40. System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(, , ));
  41. return (int)(time - startTime).TotalSeconds;
  42. }
  43.  
  44. /// <summary>
  45. /// 获取access_token
  46. /// 有效期7200秒,开发者必须在自己的服务全局缓存access_token
  47. /// </summary>
  48. /// <returns></returns>
  49. private static void GetAccessToken()
  50. {
  51. string appId = ConfigurationManager.AppSettings["appid"];//订阅号应用id
  52. string secret = ConfigurationManager.AppSettings["secret"];//订阅号应用密钥
  53. string url =
  54. "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + secret;
  55. string resStr = HttpGet(url);
  56. if (!resStr.Contains("errcode"))//string.IsNullOrEmpty(model.errcode)
  57. {
  58. //请求成功了
  59. AccessTokenModel model = JsonConvert.DeserializeObject<AccessTokenModel>(resStr);
  60. DateTime dt = DateTime.Now.AddSeconds(Convert.ToInt32(model.expires_in));
  61. objCache.Insert("AccessToken", model.access_token, null, dt, System.Web.Caching.Cache.NoSlidingExpiration);
  62. }
  63. }
  64.  
  65. /// <summary>
  66. /// HttpGet请求
  67. /// </summary>
  68. /// <param name="url"></param>
  69. /// <returns></returns>
  70. private static string HttpGet(string url)
  71. {
  72. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
  73. request.Method = "GET";
  74. request.ContentType = "text/html;charset=UTF-8";
  75. HttpWebResponse response = (HttpWebResponse)request.GetResponse();
  76. Stream myResponseStream = response.GetResponseStream();
  77. StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
  78. string retString = myStreamReader.ReadToEnd();
  79. myStreamReader.Close();
  80. myResponseStream.Close();
  81. return retString;
  82. }
  83. }
  84.  
  85. public class AccessTokenModel
  86. {
  87. public string access_token;
  88.  
  89. public string expires_in;
  90. }
  91.  
  92. public class TicketModel
  93. {
  94. public string errcode;
  95.  
  96. public string errmsg;
  97.  
  98. public string ticket;
  99.  
  100. public string expires_in;
  101. }

  ③js代码

  1. //引用jquery
  2. <script type="text/javascript" src="js/jquery.js"></script>
  3. <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
  4. <script type="text/javascript">
  5. var title = '测试标题',
  6. imgUrl = '图片地址',
  7. desc = '测试描述';
  8.  
  9. $(function () {
  10. /*
  11. wx.checkJsApi({
  12. jsApiList: [
  13. 'onMenuShareTimeline',
  14. 'onMenuShareAppMessage'
  15. ], // 需要检测的JS接口列表,所有JS接口列表见附录2,
  16. success: function (res) {
  17. allPrpos(res);
  18. // 以键值对的形式返回,可用的api值true,不可用为false
  19. // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
  20. }
  21. });
  22. */
  23.  
  24. var param = {
  25. url: location.href.split('#')[0]
  26. };
  27. //从后端请求参数
  28. AjaxPostData("url", param, function (json) {
  29. if (json.result === true) {
  30.  
  31. wx.config({
  32. debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  33. appId: json.appId, // 必填,公众号的唯一标识
  34. timestamp: json.timestamp, // 必填,生成签名的时间戳
  35. nonceStr: json.nonceStr, // 必填,生成签名的随机串
  36. signature: json.signature,// 必填,签名,见附录1
  37. menuItem: 'addContact',
  38. jsApiList: [
  39. 'onMenuShareTimeline',
  40. 'onMenuShareAppMessage'
  41. ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
  42. });
  43. }
  44. });
  45. });
  46.  
  47. wx.ready(function () {
  48. // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
  49.  
  50. //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口
  51. wx.onMenuShareTimeline({
  52. title: title, // 分享标题
  53. link: window.location.href, // 分享链接
  54. imgUrl: imgUrl, // 分享图标
  55. trigger: function (res) {
  56. //监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。
  57. //不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回。
  58. },
  59. success: function (res) {
  60. //接口调用成功时执行的回调函数。
  61. },
  62. cancel: function (res) {
  63. //用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。
  64. },
  65. fail: function (res) {
  66. //接口调用失败时执行的回调函数。
  67. },
  68. complete: function (res) {
  69. //接口调用完成时执行的回调函数,无论成功或失败都会执行。
  70. }
  71. //以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下:
  72. /*调用成功时:"xxx:ok" ,其中xxx为调用的接口名
  73. 用户取消时:"xxx:cancel",其中xxx为调用的接口名
  74. 调用失败时:其值为具体错误信息
  75. */
  76. });
  77.  
  78. //获取“分享给朋友”按钮点击状态及自定义分享内容接口
  79. wx.onMenuShareAppMessage({
  80. title: title, // 分享标题
  81. desc: desc, // 分享描述
  82. link: window.location.href, // 分享链接
  83. imgUrl: imgUrl, // 分享图标
  84. type: 'link', // 分享类型,music、video或link,不填默认为link
  85. dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
  86. success: function () {
  87. // 用户确认分享后执行的回调函数
  88. },
  89. cancel: function () {
  90. // 用户取消分享后执行的回调函数
  91. }
  92. });
  93. });
  94.  
  95. wx.error(function (res) {
  96. //allPrpos(res);
  97. // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
  98.  
  99. });
  100.  
  101. //这是我抄的我们前端开发小组的,不知道他们抄的谁的。。。
  102. var AjaxPostData = function(url, data, success) {
  103. /// <summary>
  104. /// Ajax的POST方法
  105. /// </summary>
  106. /// <param name="url" type="String">
  107. /// 网址/参数
  108. /// </param>
  109. /// <param name="data" type="JSON类型">
  110. /// 参数
  111. /// </param>
  112. /// <param name="success" type="Function">
  113. /// 回调函数,不用这个的时候为同步,用的时候为异步(有一个返回数据参数(数据))
  114. /// </param>
  115. /// <returns type="string">同步时返回数据,异步时在回调函数中取</returns>
  116.  
  117. var val = "";
  118.  
  119. var param = {
  120. url: encodeURI(url),
  121. type: "POST",
  122. timeout: 50000,
  123. async: false,
  124. data: data,
  125. dataType: "text",
  126. success: function(tempData) {},
  127. error: function(XMLHttpRequest, textStatus, errorThrown) {
  128. console.log(arguments);
  129. }
  130. };
  131.  
  132. if (!success) {
  133. param.async = false;
  134. param.success = function(tempData) {
  135. val = tempData;
  136. };
  137. } else {
  138. param.async = true;
  139. param.success = function(r) {
  140. if (success) {
  141. // var result = $(r).find('string').html();
  142. // result = result.StringToJsonObject();
  143.  
  144. var len = r.length;
  145. var result = JSON.parse(r.substring(76, len - 9));
  146.  
  147. success(result);
  148. }
  149. };
  150. }
  151.  
  152. $.ajax(param);
  153.  
  154. return val;
  155. }
  156. </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. C# POST Https请求的一些坑

    写在前面: 从上次,跟合作方的站点对接开始就产生了这个问题,当时用C#进行POST提交,总是会出现问题,找了很久发现对方的站点居然是TLS 1.2 的. 正文: 然而,在.NET FrameWork ...

  2. Oracle 数据库基础学习 (三) Oracle 四个表结构

    Oracle 四个表的 emp dept  salgrade  bunus 的结构,记住有利于后期SQL语句的学习 雇员表(emp) No. 字段 类型 描述 1 empno NUMBER(4) 表示 ...

  3. (学习笔记)HTML的<link>标签

    在HTML中<link>标签用于定义文档与外部资源的关系. <link>标签只存在于head部分. <head> <link rel="styles ...

  4. opencart 添加新模型

    1,修改模板页,复制category_list.tpl,category_form.tpl,修改成新的名称. category_list.tpl是列出页面,category_form.tpl是添加和修 ...

  5. 计划任务crontab

    安装crontab服务 1, yum install -y vixie-cron 如果提示crond命令不存在,可能被误删除了,CentOS下可以通过这个命令重新安装: yum -y install ...

  6. Guava学习笔记:Guava新集合-Table等

    Table 当我们需要多个索引的数据结构的时候,通常情况下,我们只能用这种丑陋的Map<FirstName, Map<LastName, Person>>来实现.为此Guava ...

  7. CentOS6.5安装telnet命令

    安装好memcache之后想进入连接测试,telnet localhost 11211发现竟然提示没有telnet这个命令,于是需要自己进行安装. 一.查看本机是否安装telnet #rpm -qa ...

  8. Atom 备份神器 —— Sync Settings

    当 Atom 的扩展越装越多,配置也越来越偏离了系统默认设置时,一旦电脑重装后需要复原开发环境,这将是一件比较头疼的事,但今天发现一个扩展,可以解决这一问题,那就是「Sync Settings」,根据 ...

  9. toastr 自定义提示

    在线实例 实例演示 使用方法 <button type="button" class="btn btn-primary" id="showtoa ...

  10. C# 如何实现带消息数的App图标

    上次写了一篇博文,但是每次更新图标时,桌面会闪烁(刷新),有博友说人家的图标都不会刷新,还能动画.我想了一下,如果要达到这个效果,可以用Form来实现,就是在Form中嵌入一个图片,然后用一个labe ...