Dieser Artikel beschreibt die Einführung in die C#-Entwicklung von WeChat-Portalen und -Anwendungen unter Verwendung von WeChat JSSDK zur Implementierung der Check-in-Funktion
Da WeChat nach und nach weitere JSSDK-Schnittstellen öffnet, können wir benutzerdefinierte verwenden Auf Webseiten können wir mehr WeChat-Schnittstellen aufrufen, um unsere umfangreicheren Schnittstellenfunktionen und -effekte zu erzielen. Beispielsweise können wir verschiedene Mobiltelefon-Hardware auf der Seite aufrufen, um Informationen wie Kamerafotografie, GPS-Informationen, Scannen von QR-Codes usw. zu erhalten In diesem Artikel wird erläutert, wie diese JSSDK-Schnittstellen zum Implementieren der Check-in-Funktion verwendet werden. Beim Check-in müssen geografische Koordinaten und Adressen gemeldet, die Kamera aufgerufen werden, um Bilder in Echtzeit aufzunehmen, und relevante Informationen über den aktuellen Benutzer usw. eingeholt werden.
1. Beschreibung von JSSDK
WeChat JS-SDK ist ein Webentwicklungs-Toolkit, das auf WeChat basiert und von der öffentlichen WeChat-Plattform für Webentwickler bereitgestellt wird. Durch die Verwendung von WeChat JS-SDK können Webentwickler WeChat nutzen, um die Funktionen von Mobiltelefonsystemen wie Aufnehmen von Bildern, Auswählen von Bildern, Sprache und Standort effizient zu nutzen. Gleichzeitig können sie die einzigartigen Funktionen von WeChat direkt nutzen, z. Scannen, Gutscheine und Bezahlen, um WeChat-Benutzern ein besseres Web-Erlebnis zu bieten.
Die derzeit von JSSDK unterstützten Schnittstellenkategorien umfassen die folgenden Kategorien: Basisschnittstelle, Freigabeschnittstelle, Bildschnittstelle, Audioschnittstelle, Smart-Schnittstelle, Geräteinformationen, geografischer Standort, Shake-Peripheriegeräte, Schnittstellenbedienung, WeChat-Scan, WeChat-Shop , WeChat-Gutscheine, WeChat-Zahlung, mit der Integration aller WeChat-Funktionen werden voraussichtlich nacheinander weitere Schnittstellen geöffnet.
Geben Sie das Modul [Entwicklerdokumentation] in das WeChat-Backend ein, und wir können die funktionale Klassifizierung und Einführung des entsprechenden JSSDK sehen, wie unten gezeigt.
Auf der rechten Seite können wir die Verwendungsanweisungen für jede Schnittstelle im Detail sehen. Grundsätzlich sind die Verwendungsmethoden von JSSDK ähnlich, sodass Sie das Debugging und das Master-Verfahren bestehen können oder zwei davon, und die anderen folgen einfach den Anweisungen und befolgen sie.
1) Schritte zur Verwendung von JSSDK
Schritt 1: Domänennamen binden
Melden Sie sich zunächst bei der öffentlichen WeChat-Plattform an und geben Sie die „Funktionseinstellungen“ der „Offiziellen Kontoeinstellungen“ ein ", um die „JS-Schnittstelle“ „Sicherer Domänenname“ auszufüllen. Richten Sie es wie unten gezeigt auf der öffentlichen Plattform ein.
Hinweis: Nach dem Login können Sie die entsprechenden Schnittstellenberechtigungen im „Developer Center“ einsehen.
Schritt 2: JS-Dateien einführen
Fügen Sie die folgenden JS-Dateien auf der Seite ein, die die JS-Schnittstelle aufrufen muss (unterstützt https): http://res .wx.qq .com/open/js/jweixin-1.0.0.js
Wenn Sie die Shake-Peripheriefunktion verwenden müssen, importieren Sie bitte http://res.wx.qq.com/open/ js/jweixin-1.1 .0.js
Hinweis: Unterstützt das Laden mit der AMD/CMD-Standard-Modullademethode
Natürlich bearbeiten wir die Seite im Allgemeinen, um mehr Effekte zu ermöglichen kann auch andere JS-Bibliotheken einführen, z. B. JQuery-Klassenbibliotheken usw. Darüber hinaus können wir auch umfangreichere Funktionen basierend auf der jquery-weui-Klassenbibliothek implementieren. Das Folgende ist die JS-Referenz in unserem Fallcode.
<script src="~/Content/wechat/jquery-weui/lib/jquery-2.1.4.js"></script> <script src="~/Content/wechat/jquery-weui/js/jquery-weui.js"></script> <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"></script>
Schritt 3: Berechtigungsüberprüfungskonfiguration über die Konfigurationsschnittstelle einfügen
Alle Seiten, die JS-SDK verwenden müssen, müssen zuerst Konfigurationsinformationen einfügen, andernfalls werden sie nicht aufgerufen (das Gleiche). Die URL muss nur einmal aufgerufen werden, und die Web-App des SPA, die die URL ändert, kann jedes Mal aufgerufen werden, wenn sich die URL ändert. Derzeit unterstützt der Android WeChat-Client die neue H5-Funktion von pushState nicht, daher wird pushState zum Implementieren des Webs verwendet Die App-Seite führt dazu, dass die Signatur fehlschlägt. Dieses Problem wird in Android 6.2 behoben.
wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '', // 必填,公众号的唯一标识 timestamp: , // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名,见附录1 jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 });
Die obige Konfiguration ist der Kern von JSSDK. Sie muss die entsprechende App-ID, den Zeitstempel und den NonceStr konfigurieren. Das Bemerkenswerteste daran ist der Implementierungsmechanismus Auf diese Weise generieren wir einfach den entsprechenden Wert im Hintergrund und weisen ihn der JS-Seite zu. Dies ist auch der sicherste Ansatz.
Der folgende Code ist der HTML-Code auf der Asp.net-Ansichtsseite in unserem aktuellen Projekt, wie unten gezeigt.
<script language="javascript"> var appid = '@ViewBag.appid'; var noncestr = '@ViewBag.noncestr'; var signature = '@ViewBag.signature'; var timestamp = '@ViewBag.timestamp'; wx.config({ debug: false, appId: appid, // 必填,公众号的唯一标识 timestamp: timestamp, // 必填,生成签名的时间戳 nonceStr: noncestr, // 必填,生成签名的随机串 signature: signature, // 必填,签名,见附录1 jsApiList: [ 'checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone', 'hideMenuItems', 'showMenuItems', 'hideAllNonBaseMenuItem', 'showAllNonBaseMenuItem', 'translateVoice', 'startRecord', 'stopRecord', 'onVoiceRecordEnd', 'playVoice', 'onVoicePlayEnd', 'pauseVoice', 'stopVoice', 'uploadVoice', 'downloadVoice', 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage', 'getNetworkType', 'openLocation', 'getLocation', 'hideOptionMenu', 'showOptionMenu', 'closeWindow', 'scanQRCode', 'chooseWXPay', 'openProductSpecificView', 'addCard', 'chooseCard', 'openCard' ] });
Schritt 4: Erfolgreiche Überprüfung über die fertige Schnittstelle verarbeiten
wx.ready(function(){ // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口, //则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。 });
Diese fertige Schnittstelle ist der Verarbeitungsinhalt, nachdem die Seite erfolgreich geladen wurde. Im Allgemeinen müssen wir viel tun Operationen erfordern, dass die relevanten Objekte erst nach dem Laden der Seite zur Zuweisung, Verarbeitung und anderen Vorgängen aufgerufen werden können.
Nachdem die Seite beispielsweise fertig ist, können wir die entsprechenden GPS-Koordinaten und andere Vorgänge abrufen, die mit dem folgenden JS-Code implementiert werden können.
wx.ready(function () { wx.getLocation({ type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02' success: function (res) { var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90 var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。 var speed = res.speed; // 速度,以米/每秒计 var accuracy = res.accuracy; // 位置精度 $("#lblLoacation").text(latitude + "," + longitude); } }); });
Schritt 5: Behandeln Sie fehlgeschlagene Überprüfungen über die Fehlerschnittstelle
wx.error(function(res){ // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看, // 也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 });
Diese Fehlerschnittstelle wird auch zur Verarbeitung von Ausnahmeinformationen verwendet. Unter normalen Umständen können Benutzer hier zu Fehlern aufgefordert werden . .
2), Signaturalgorithmus
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
即signature=sha1(string1)。 示例:
noncestr=Wm3WZYTPz0wzccnW jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg timestamp=1414587457 url=http://mp.weixin.qq.com?params=value
步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
步骤2. 对string1进行sha1签名,得到signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed
注意事项
1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
2.签名用的url必须是调用JS接口页面的完整URL。
3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。
如出现invalid signature 等错误详见附录5常见错误及解决办法。
以上就是JSSDK总体的使用流程,虽然看起来比较抽象,但是基本上也就是这些步骤了。
上面的过程是具体的参数处理逻辑,我们要对应到C#代码的签名实现,需要对几个变量进行处理,下面是对应的生成noncestr、timestamp、以及签名等操作的代码。
/// <summary> /// 生成时间戳,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数 /// </summary> /// <returns>时间戳</returns> private static string GetTimeStamp() { TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds).ToString(); } /// <summary> /// 生成随机串,随机串包含字母或数字 /// </summary> /// <returns>随机串</returns> private static string GetNonceStr() { return Guid.NewGuid().ToString().Replace("-", ""); }
还有我们要实现JSSDK签名的处理,必须先根据几个变量,构建好URL字符串,具体的处理过程,我们可以把它们逐一放在一个Hashtable里面,如下代码所示。
/// <summary> /// 获取JSSDK所需要的参数信息,返回Hashtable结合 /// </summary> /// <param name="appId">微信AppID</param> /// <param name="jsTicket">根据Token获取到的JSSDK ticket</param> /// <param name="url">页面URL</param> /// <returns></returns> public static Hashtable GetParameters(string appId, string jsTicket, string url) { string timestamp = GetTimeStamp(); string nonceStr = GetNonceStr(); // 这里参数的顺序要按照 key 值 ASCII 码升序排序 string rawstring = "jsapi_ticket=" + jsTicket + "&noncestr=" + nonceStr + "×tamp=" + timestamp + "&url=" + url + ""; string signature = GetSignature(rawstring); Hashtable signPackage = new Hashtable(); signPackage.Add("appid", appId); signPackage.Add("noncestr", nonceStr); signPackage.Add("timestamp", timestamp); signPackage.Add("url", url); signPackage.Add("signature", signature); signPackage.Add("jsapi_ticket", jsTicket); signPackage.Add("rawstring", rawstring); return signPackage; }
我们注意到URL参数的字符串组合:
string rawstring = "jsapi_ticket=" + jsTicket + "&noncestr=" + nonceStr + "×tamp=" + timestamp + "&url=" + url + "";
这里我们拼接好URL参数后,就需要使用签名的规则来实现签名的处理了,签名的代码如下所示,注释代码和上面代码等同。
/// <summary> /// 使用SHA1哈希加密算法生成签名 /// </summary> /// <param name="rawstring">待处理的字符串</param> /// <returns></returns> private static string GetSignature(string rawstring) { return FormsAuthentication.HashPasswordForStoringInConfigFile(rawstring, "SHA1").ToLower(); ////下面和上面代码等价 //SHA1 sha1 = new SHA1CryptoServiceProvider(); //byte[] bytes_sha1_in = System.Text.UTF8Encoding.Default.GetBytes(rawstring); //byte[] bytes_sha1_out = sha1.ComputeHash(bytes_sha1_in); //string signature = BitConverter.ToString(bytes_sha1_out); //signature = signature.Replace("-", "").ToLower(); //return signature; }
这样我们有了对应的值后,我们就可以把它们的参数全部放在集合里面了供使用。
/// <summary> /// 获取用于JS-SDK的相关参数列表(该方法对accessToken和JSTicket都进行了指定时间的缓存处理,多次调用不会重复生成) /// 集合里面包括jsapi_ticket、noncestr、timestamp、url、signature、appid、rawstring /// </summary> /// <param name="appid">应用ID</param> /// <param name="appSecret">开发者凭据</param> /// <param name="url">页面URL</param> /// <returns></returns> public Hashtable GetJSAPI_Parameters(string appid, string appSecret, string url) { string accessToken = GetAccessToken(appid, appSecret); string jsTicket = GetJSAPI_Ticket(accessToken); return JSSDKHelper.GetParameters(appid, jsTicket, url); }
下面我们通过具体的代码案例来介绍使用的过程。
2、签到功能的实现处理
其实签到,都可以在微信公众号和企业号实现,微信的企业号可能实现更佳一些,不过他们使用JSSDK的接口操作是一样的,我们可以拓展过去就可以了。这里介绍微信公众号JSSDK实现签到的功能处理。
签到的功能,我们希望记录用户的GPS位置信息,还有就是利用拍照功能,拍一个照片同时上传到服务器,这样我们就可以实现整个业务效果了。
首先我们来设计签到的界面,代码及效果如下所示。
界面预览效果如下所示:
我们来看看微信JSSDK里面对于【获取地理位置接口】的说明:
wx.getLocation({ type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02' success: function (res) { var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90 var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。 var speed = res.speed; // 速度,以米/每秒计 var accuracy = res.accuracy; // 位置精度 } });
以及图形接口里面【拍照或从手机相册中选图接口】的说明:
wx.chooseImage({ count: 1, // 默认9 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 success: function (res) { var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片 } });
上传图片到微信服务器接口如下所示。
wx.uploadImage({ localId: '', // 需要上传的图片的本地ID,由chooseImage接口获得 isShowProgressTips: 1, // 默认为1,显示进度提示 success: function (res) { var serverId = res.serverId; // 返回图片的服务器端ID } });
备注:上传图片有效期3天,可用微信多媒体接口下载图片到自己的服务器,此处获得的 serverId 即 media_id。
根据这几个接口,我们来对它们进行包装,以实现我们的业务需求。根据我们的需要,我们对JSSDK接口进行了调用,如下所示。
<script language="javascript"> var appid = '@ViewBag.appid'; var noncestr = '@ViewBag.noncestr'; var signature = '@ViewBag.signature'; var timestamp = '@ViewBag.timestamp'; wx.config({ debug: false, appId: appid, // 必填,公众号的唯一标识 timestamp: timestamp, // 必填,生成签名的时间戳 nonceStr: noncestr, // 必填,生成签名的随机串 signature: signature, // 必填,签名,见附录1 jsApiList: [ 'checkJsApi', 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage', 'getNetworkType', 'openLocation', 'getLocation' ] }); wx.ready(function () { wx.getLocation({ type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02' success: function (res) { var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90 var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。 var speed = res.speed; // 速度,以米/每秒计 var accuracy = res.accuracy; // 位置精度 $("#lblLoacation").text(latitude + "," + longitude); //解析坐标地址 var location = latitude + "," + longitude; $.ajax({ type: 'GET', url: '/JSSDKTest/GetAddress?location=' + location, //async: false, //同步 //dataType: 'json', success: function (json) { $("#lblAddress").text(json); }, error: function (xhr, status, error) { $.messager.alert("提示", "操作失败" + xhr.responseText); //xhr.responseText } }); } }); wx.getNetworkType({ success: function (res) { var networkType = res.networkType; // 返回网络类型2g,3g,4g,wifi $("#lblNetwork").text(networkType); } }); chooseImage(); }); </script>
其中的chooseImage()是我们在页面开始的时候,让用户拍照的操作,具体JS代码如下所示。
//拍照显示 var localIds; function chooseImage() { wx.chooseImage({ count: 1, // 默认9 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourceType: ['camera'], // 可以指定来源是相册还是相机,默认二者都有 success: function (res) { localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片 $("#imgUpload").attr("src", localIds); } }); }
但用户使用摄像头拍照后,就会返回一个res.localIds集合,因为我们拍照一个,那么可以把它直接赋值给图片对象,让它显示当前拍照的图片。
拍照完成,我们单击【签到】应该把图片和相关的坐标等信息上传到服务器的,图片首先是保存在微信服务器的,上传图片有效期3天,可用微信多媒体接口下载图片到自己的服务器,此处获得的 serverId 即 media_id。
为了实现我们自己的业务数据,我们需要把图片集相关信息存储在自己的服务器,这样才可以实现信息的保存,最后提示【签到操作成功】,具体过程如下所示。
//上传图片 var serverId; function upload() { wx.uploadImage({ localId: localIds[0], success: function (res) { serverId = res.serverId; //提交数据到服务器 //提示信息 $.toast("签到操作成功"); }, fail: function (res) { alert(JSON.stringify(res)); } }); }
另外,我们为了实现单击图片控件,实现重新拍照的操作,以及签到的事件处理,我们对控件的单击处理进行了绑定,如下代码所示。
document.querySelector('#imgUpload').onclick = function () { chooseImage(); }; $(document).on("click", "#btnSignIn", function () { if (localIds == undefined || localIds== null) { $.toast('请先拍照', "forbidden"); return; } //调用上传图片获得媒体ID upload(); });
Das obige ist der detaillierte Inhalt vonEinführung in die Entwicklung von WeChat-Portalen und -Anwendungen mit C# zur Implementierung der Check-in-Funktion mit WeChat JSSDK. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!