using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.IO; using Newtonsoft.Json; using System.Net; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Security.Cryptography; /// <summary> /// WXJSSDK 的摘要說明 /// </summary> public class WXJSSDK { private string appId; private string appSecret; private DataTable DT; public WXJSSDK(string appId, string appSecret) { this.appId = appId; this.appSecret = appSecret; } //得到數(shù)據(jù)包,返回使用頁面 public System.Collections.Hashtable getSignPackage() { string jsapiTicket = getJsApiTicket(); string url = HttpContext.Current.Request.Url.ToString(); string timestamp = Convert.ToString(ConvertDateTimeInt(DateTime.Now)); string nonceStr = createNonceStr(); // 這里參數(shù)的順序要按照 key 值 ASCII 碼升序排序 string rawstring = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + nonceStr + "×tamp=" + timestamp + "&url=" + url + ""; string signature = SHA1_Hash(rawstring); System.Collections.Hashtable signPackage = new System.Collections.Hashtable(); signPackage.Add("appId", appId); signPackage.Add("nonceStr", nonceStr); signPackage.Add("timestamp", timestamp); signPackage.Add("url", url); signPackage.Add("signature", signature); signPackage.Add("rawString", rawstring); return signPackage; } //創(chuàng)建隨機(jī)字符串 private string createNonceStr() { int length = 16; string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; string str = ""; Random rad = new Random(); for (int i = 0; i < length; i++) { str += chars.Substring(rad.Next(0, chars.Length - 1), 1); } return str; } //得到ticket 如果文件里時(shí)間 超時(shí)則重新獲取 //注:jsapi_ticket使用規(guī)則(有過期時(shí)間)類似access_token, oauth的access_token與基礎(chǔ)access_token不同 private string getJsApiTicket() { //這里我從數(shù)據(jù)庫讀取 DT = DbSession.Default.FromSql("select jsapi_ticket,ticket_expires from table where ID=1").ToDataTable(); int expire_time = (int)DT.Rows[0]["ticket_expires"]; string ticket = DT.Rows[0]["jsapi_ticket"].ToString(); string accessToken =getAccessToken();//獲取系統(tǒng)的全局token if (expire_time < ConvertDateTimeInt(DateTime.Now)) { string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=" + accessToken + ""; Jsapi api =JsonConvert.DeserializeObject<Jsapi>(httpGet(url)); ticket = api.ticket; if (ticket != "") { expire_time = ConvertDateTimeInt(DateTime.Now) + 7000; //存入數(shù)據(jù)庫操作 } } return ticket; } ////得到accesstoken 如果文件里時(shí)間 超時(shí)則重新獲取 //private string getAccessToken() //{ // // access_token 應(yīng)該全局存儲與更新,以下代碼以寫入到文件中做示例 // string access_token = ""; // string path = HttpContext.Current.Server.MapPath(@"/weixin/access_token.json"); // FileStream file = new FileStream(path, FileMode.Open); // var serializer = new DataContractJsonSerializer(typeof(AccToken)); // AccToken readJSTicket = (AccToken)serializer.ReadObject(file); // file.Close(); // if (readJSTicket.expires_in < ConvertDateTimeInt(DateTime.Now)) // { // string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret + ""; // AccToken iden = Desrialize<AccToken>(new AccToken(), httpGet(url)); // access_token = iden.access_token; // if (access_token != "") // { // iden.expires_in = ConvertDateTimeInt(DateTime.Now) + 7000; // iden.access_token = access_token; // string json = Serialize<AccToken>(iden); // StreamWriterMetod(json, path); // } // } // else // { // access_token = readJSTicket.access_token; // } // return access_token; //} //發(fā)起一個(gè)http請球,返回值 private string httpGet(string url) { try { WebClient MyWebClient = new WebClient(); MyWebClient.Credentials = CredentialCache.DefaultCredentials;//獲取或設(shè)置用于向Internet資源的請求進(jìn)行身份驗(yàn)證的網(wǎng)絡(luò)憑據(jù) Byte[] pageData = MyWebClient.DownloadData(url); //從指定網(wǎng)站下載數(shù)據(jù) string pageHtml = System.Text.Encoding.Default.GetString(pageData); //如果獲取網(wǎng)站頁面采用的是GB2312,則使用這句 return pageHtml; } catch (WebException webEx) { Console.WriteLine(webEx.Message.ToString()); return null; } } //SHA1哈希加密算法 public string SHA1_Hash(string str_sha1_in) { SHA1 sha1 = new SHA1CryptoServiceProvider(); byte[] bytes_sha1_in = System.Text.UTF8Encoding.Default.GetBytes(str_sha1_in); byte[] bytes_sha1_out = sha1.ComputeHash(bytes_sha1_in); string str_sha1_out = BitConverter.ToString(bytes_sha1_out); str_sha1_out = str_sha1_out.Replace("-", "").ToLower(); return str_sha1_out; } /// <summary> /// StreamWriter寫入文件方法 /// </summary> private void StreamWriterMetod(string str, string patch) { try { FileStream fsFile = new FileStream(patch, FileMode.OpenOrCreate); StreamWriter swWriter = new StreamWriter(fsFile); swWriter.WriteLine(str); swWriter.Close(); } catch (Exception e) { throw e; } } /// <summary> /// 將c# DateTime時(shí)間格式轉(zhuǎn)換為Unix時(shí)間戳格式 /// </summary> /// <param name="time">時(shí)間</param> /// <returns>double</returns> public int ConvertDateTimeInt(System.DateTime time) { int intResult = 0; System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); intResult = Convert.ToInt32((time - startTime).TotalSeconds); return intResult; } } //創(chuàng)建Json序列化 及反序列化類目 #region //創(chuàng)建JSon類 保存文件 jsapi_ticket.json public class JSTicket { public string jsapi_ticket { get; set; } public double expire_time { get; set; } } //創(chuàng)建 JSon類 保存文件 access_token.json public class AccToken { public string access_token { get; set; } public double expires_in { get; set; } } //創(chuàng)建從微信返回結(jié)果的一個(gè)類 用于獲取ticket public class Jsapi { public int errcode { get; set; } public string errmsg { get; set; } public string ticket { get; set; } public string expires_in { get; set; } } #endregion
上面是寫好的類,接下來直接呼叫後對應(yīng)輸出給js
WXJSSDK jssdk = new WXJSSDK(AppId,AppSecret); Hashtable hs = jssdk.getSignPackage(); string signature = hs["signature"].ToString(); string signature = hs["signature"].ToString(); string timestamp = hs["timestamp"].ToString(); string nonce = hs["nonceStr"].ToString();
接著js呼叫:
<script type="text/javascript"> var dataForWeixin = { appId: "<%=appid%>", MsgImg: "<%=WeChatImg%>", TLImg: "<%=WeChatImg%>", url: "<%=url%>", title: "<%=Title%>", desc: "<%=desc%>", timestamp: '<%=timestamp%>', nonceStr: '<%=nonce%>', signature: '<%=signature%>', jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo'], fakeid: "", callback: function () { } }; wx.config({ debug: false, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會通過log打出,僅在pc端時(shí)才會打印。 appId: dataForWeixin.appId, // 必填,公眾號的唯一標(biāo)識 timestamp: dataForWeixin.timestamp, // 必填,生成簽名的時(shí)間戳 nonceStr: dataForWeixin.nonceStr, // 必填,生成簽名的隨機(jī)串 signature: dataForWeixin.signature,// 必填,簽名,見附錄1 jsApiList: dataForWeixin.jsApiList // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2 }); wx.ready(function () { //在此輸入各種API //分享到朋友圈 wx.onMenuShareTimeline({ title: dataForWeixin.title, // 分享標(biāo)題 link: dataForWeixin.url, // 分享鏈接 imgUrl: dataForWeixin.MsgImg, // 分享圖標(biāo) success: function () { // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù) }, cancel: function () { // 用戶取消分享后執(zhí)行的回調(diào)函數(shù) } }); //分享給朋友 wx.onMenuShareAppMessage({ title: dataForWeixin.title, // 分享標(biāo)題 desc: dataForWeixin.desc, // 分享描述 link: dataForWeixin.url, // 分享鏈接 imgUrl: dataForWeixin.TLImg, // 分享圖標(biāo) type: '', // 分享類型,music、video或link,不填默認(rèn)為link dataUrl: '', // 如果type是music或video,則要提供數(shù)據(jù)鏈接,默認(rèn)為空 success: function () { // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù) }, cancel: function () { // 用戶取消分享后執(zhí)行的回調(diào)函數(shù) } }); //QQ wx.onMenuShareQQ({ title: dataForWeixin.title, // 分享標(biāo)題 desc: dataForWeixin.desc, // 分享描述 link: dataForWeixin.url, // 分享鏈接 imgUrl: dataForWeixin.MsgImg,// 分享圖標(biāo) success: function () { // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù) }, cancel: function () { // 用戶取消分享后執(zhí)行的回調(diào)函數(shù) } }); //QQ微博 wx.onMenuShareWeibo({ title: dataForWeixin.title, // 分享標(biāo)題 desc: dataForWeixin.desc, // 分享描述 link: dataForWeixin.url, // 分享鏈接 imgUrl: dataForWeixin.TLImg, // 分享圖標(biāo) success: function () { // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù) }, cancel: function () { // 用戶取消分享后執(zhí)行的回調(diào)函數(shù) } }); // config信息驗(yàn)證后會執(zhí)行ready方法,所有接口調(diào)用都必須在config接口獲得結(jié)果之后,config是一個(gè)客戶端的異步操作, //所以如果需要在頁面加載時(shí)就調(diào)用相關(guān)接口,則須把相關(guān)接口放在ready函數(shù)中調(diào)用來確保正確執(zhí)行。對于用戶觸發(fā)時(shí)才調(diào)用的接口,則可以直接調(diào)用,不需要放在ready函數(shù)中。 }); wx.error(function (res) { //alert(res); // config信息驗(yàn)證失敗會執(zhí)行error函數(shù),如簽名過期導(dǎo)致驗(yàn)證失敗,具體錯(cuò)誤信息可以打開config的debug模式查看,也可以在返回的res參數(shù)中查看,對于SPA可以在這里更新簽名。 }); </script>
更多微信開發(fā)-Jssdk調(diào)用分享實(shí)例
本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool
免費(fèi)脫衣圖片

Undresser.AI Undress
人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章
Grass Wonder Build Guide |烏瑪媽媽漂亮的德比
4 週前
By Jack chen
<??>:在森林裡99夜 - 所有徽章以及如何解鎖
3 週前
By DDD
烏瑪?shù)姆劢z漂亮的德比橫幅日程(2025年7月)
4 週前
By Jack chen
Rimworld Odyssey溫度指南和Gravtech
3 週前
By Jack chen
Windows安全是空白或不顯示選項(xiàng)
4 週前
By 下次還敢

熱工具

記事本++7.3.1
好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6
視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)