微信網站設置右上角發送、分享的內容——.net版本

1、首先了解本文要解決的問題:javascript

    公司前一段開發了移動網站,老闆喜歡經過微信看,而後把看到的東西經過右上角的按鈕分享出來,但老闆發現分享出來的東西,沒有指定的圖片,沒有描述;因此我就得老老實實幹活了。。。php

  以下圖所示:html

  

  點擊發送給朋友,或者分享到朋友圈時,須要帶上老闆指定的圖片、描述和標題。前端

 

2、嘗試解決問題java

  剛開始,經過網上查閱,發現微信會自動抓取頁面的title屬性做爲標題,和頁面中第一張尺寸大於等於300*300的圖片,做爲分享出來的圖片,因而帶着偷懶的想法先這樣嘗試了一下,會有一下幾個問題:node

    ①不能自定義描述信息python

    ②當頁面內沒有超過300*300的圖片時,就不能顯示圖片了,因而我放了一張300*300的公司的logo在每一個頁面內,首先老闆並不喜歡,其次會影響加載速度,同時當用戶在隱藏圖片還沒加載出來的時候就進行分享動做,那麼圖片仍是識別不出來。。。jquery

 

  改完第一次,用了一段時間,老闆不滿意,要求繼續優化,因而第二版開始更新。。web

  既然不能走野路子,只能經過微信給出的開發文檔進行更改了。。請參考官網文檔:http://mp.weixin.qq.com/wiki/7/1c97470084b73f8e224fe6d9bab1625b.htmlajax

  微信發佈了《微信JS-SDK說明文檔》供開發者使用,而且給出了示例,包含了php、java、nodejs、python示例,然而並無什麼卵用!由於我是一個.net開發!!!

  只能本身動手,豐衣足食了。

 

3、說幹就幹

  代碼分兩個部分,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(0, sb.ToString().Length - 1);
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(1970, 1, 1));
 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 
 66     /// <summary>
 67     /// HttpGet請求
 68     /// </summary>
 69     /// <param name="url"></param>
 70     /// <returns></returns>
 71     private static string HttpGet(string url)
 72     {
 73         HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
 74         request.Method = "GET";
 75         request.ContentType = "text/html;charset=UTF-8";
 76         HttpWebResponse response = (HttpWebResponse)request.GetResponse();
 77         Stream myResponseStream = response.GetResponseStream();
 78         StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
 79         string retString = myStreamReader.ReadToEnd();
 80         myStreamReader.Close();
 81         myResponseStream.Close();
 82         return retString;
 83     }
 84 }
 85 
 86 public class AccessTokenModel
 87 {
 88     public string access_token;
 89 
 90     public string expires_in;
 91 }
 92 
 93 public class TicketModel
 94 {
 95     public string errcode;
 96 
 97     public string errmsg;
 98 
 99     public string ticket;
100 
101     public string expires_in;
102 }

  ③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         //獲取「分享到朋友圈」按鈕點擊狀態及自定義分享內容接口
 52         wx.onMenuShareTimeline({
 53             title: title, // 分享標題
 54             link: window.location.href, // 分享連接
 55             imgUrl: imgUrl, // 分享圖標
 56             trigger: function (res) {
 57                 //監聽Menu中的按鈕點擊時觸發的方法,該方法僅支持Menu中的相關接口。
 58                 //不要嘗試在trigger中使用ajax異步請求修改本次分享的內容,由於客戶端分享操做是一個同步操做,這時候使用ajax的回包會尚未返回。
 59             },
 60             success: function (res) {
 61                 //接口調用成功時執行的回調函數。
 62             },
 63             cancel: function (res) {
 64                 //用戶點擊取消時的回調函數,僅部分有用戶取消操做的api纔會用到。
 65             },
 66             fail: function (res) {
 67                 //接口調用失敗時執行的回調函數。
 68             },
 69             complete: function (res) {
 70                 //接口調用完成時執行的回調函數,不管成功或失敗都會執行。
 71             }
 72             //以上幾個函數都帶有一個參數,類型爲對象,其中除了每一個接口自己返回的數據以外,還有一個通用屬性errMsg,其值格式以下:
 73             /*調用成功時:"xxx:ok" ,其中xxx爲調用的接口名
 74             用戶取消時:"xxx:cancel",其中xxx爲調用的接口名
 75             調用失敗時:其值爲具體錯誤信息
 76         */
 77         });
 78 
 79 
 80         //獲取「分享給朋友」按鈕點擊狀態及自定義分享內容接口
 81         wx.onMenuShareAppMessage({
 82             title: title, // 分享標題
 83             desc: desc, // 分享描述
 84             link: window.location.href, // 分享連接
 85             imgUrl: imgUrl, // 分享圖標
 86             type: 'link', // 分享類型,music、video或link,不填默認爲link
 87             dataUrl: '', // 若是type是music或video,則要提供數據連接,默認爲空
 88             success: function () {
 89                 // 用戶確認分享後執行的回調函數
 90             },
 91             cancel: function () {
 92                 // 用戶取消分享後執行的回調函數
 93             }
 94         });
 95     });
 96 
 97     wx.error(function (res) {
 98         //allPrpos(res);
 99         // config信息驗證失敗會執行error函數,如簽名過時致使驗證失敗,具體錯誤信息能夠打開config的debug模式查看,也能夠在返回的res參數中查看,對於SPA能夠在這裏更新簽名。
100 
101     });
102 
103     //這是我抄的咱們前端開發小組的,不知道他們抄的誰的。。。
104     var AjaxPostData = function(url, data, success) {
105         ///    <summary>
106         ///        Ajax的POST方法
107         ///    </summary>
108         ///    <param name="url" type="String">
109         ///        網址/參數
110         /// </param>
111         ///    <param name="data" type="JSON類型">
112         ///        參數
113         /// </param>
114         ///    <param name="success" type="Function">
115         ///        回調函數,不用這個的時候爲同步,用的時候爲異步(有一個返回數據參數(數據))
116         /// </param>
117         ///    <returns type="string">同步時返回數據,異步時在回調函數中取</returns>
118 
119         var val = "";
120 
121         var param = {
122             url: encodeURI(url),
123             type: "POST",
124             timeout: 50000,
125             async: false,
126             data: data,
127             dataType: "text",
128             success: function(tempData) {},
129             error: function(XMLHttpRequest, textStatus, errorThrown) {
130                 console.log(arguments);
131             }
132         };
133 
134         if (!success) {
135             param.async = false;
136             param.success = function(tempData) {
137                 val = tempData;
138             };
139         } else {
140             param.async = true;
141             param.success = function(r) {
142                 if (success) {
143                     //                    var result = $(r).find('string').html();
144                     //                    result = result.StringToJsonObject();
145 
146                     var len = r.length;
147                     var result = JSON.parse(r.substring(76, len - 9));
148 
149                     success(result);
150                 }
151             };
152         }
153 
154         $.ajax(param);
155 
156         return val;
157     }
158 </script>
相關文章
相關標籤/搜索