本覺得接入微信JS-SDK是一件很簡單的事情,結果掉坑裏好幾天,查閱了各類沒用的資料,終於翻山倒海的倒騰出來了,我要記下來,但願後面的人看到的這個文章能幫助你早點爬出坑來
登陸到你的微信公衆平臺後,左側菜單選擇設置-》公衆號設置-》功能設置-》JS接口安全域名。它的上面給你列出了幾個注意事項,好比要備案經過的域名,要將MP_verify_nnbEERhXNfbMC8Z0.txt上傳到服務器,這一步按照操做便可,這時會像你所填寫的這個地址發送一個請求裏面,你接受到後還須要利用sha1加密進行比較html
Nodejs代碼:express
var express = require('express'); var crypto = require('crypto'); //引入加密模塊 var config = require('./config');//引入配置文件 var http = require('http'); var app = express(); app.get('/wx', function (req, res) { //1.獲取微信服務器Get請求的參數 signature、timestamp、nonce、echostr var signature = req.query.signature,//微信加密簽名 timestamp = req.query.timestamp,//時間戳 nonce = req.query.nonce,//隨機數 echostr = req.query.echostr;//隨機字符串 //2.將token、timestamp、nonce三個參數進行字典序排序 var array = [config.token, timestamp, nonce]; array.sort(); //3.將三個參數字符串拼接成一個字符串進行sha1加密 var tempStr = array.join(''); const hashCode = crypto.createHash('sha1'); //建立加密類型 var resultCode = hashCode.update(tempStr, 'utf8').digest('hex'); //對傳入的字符串進行加密 console.log(signature) //4.開發者得到加密後的字符串可與signature對比,標識該請求來源於微信 if (resultCode === signature) { res.send(echostr); } else { res.send('mismatch'); } }); var server = app.listen(3000, function () { var host = server.address().address; var port = server.address().port; console.log('Example app listening at http://%s:%s', host, port); });
config文件代碼:json
{ "token":"test", "appId":"wx1c9dedd4d06c8f14", "appSecret":"07b365cb9e600b5ce04915f59623eb99" }
官方提供的http://203.195.235.76/jssdk/ 這個仍是頗有幫助的,前臺的配置都是從這裏面複製過去的,首先建立html頁面,用來調用接口實現功能,這裏須要注意下,沒有認證的訂閱號有些接口沒法調用(具體的權限看百度結果:https://jingyan.baidu.com/art...)api
我這裏調用圖片拍照/手機選擇這個功能,建立Image.html頁面,Image.html代碼以下:(這裏面的代碼大部分都是複製官方提供的那個頁面的,這不是重點)瀏覽器
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>選擇圖像</title> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0"> </head> <body> <button class="btn btn_primary" id="checkJsApi">checkJsApi</button> <h3 id="menu-image">圖像接口</h3> <span class="desc">拍照或從手機相冊中選圖接口</span> <button class="btn btn_primary" id="chooseImage">chooseImage</button> </body> <script src="http://203.195.235.76/jssdk/js/zepto.min.js"></script> <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script> $.get("http:/xx.xx.cn/getsign", function (res) { console.log(res) wx.config({ debug: true, // 開啓調試模式 appId: "你的appid", // 必填,公衆號的惟一標識 timestamp: res.timestamp, // 必填,生成簽名的時間戳 nonceStr: res.noncestr, // 必填,生成簽名的隨機串 signature: res.signature,// 必填,簽名,見附錄1 jsApiList: ['chooseImage', 'previewImage', 'uploadImage', 'downloadImage'] // 必填,須要使用的JS接口列表,全部JS接口列表見附錄2 }); }) </script> <script> wx.error(function(res){ console.log(JSON.stringify(res)) }) wx.ready(function () { // 1 判斷當前版本是否支持指定 JS 接口,支持批量判斷 document.querySelector('#checkJsApi').onclick = function () { wx.checkJsApi({ jsApiList: [ 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage' ], success: function (res) { alert(JSON.stringify(res)); } }); }; // 5 圖片接口 // 5.1 拍照、本地選圖 var images = { localId: [] }; document.querySelector('#chooseImage').onclick = function () { wx.chooseImage({ success: function (res) { images.localId = res.localIds; alert('已選擇 ' + res.localIds.length + ' 張圖片'); }, error:function(res){ alert("error") alert("res") } }); }; }) </script> </html>
終於到了這幾天一直卡在的點上,反反覆覆的config:invalid signature錯誤,後面終於發現問題,1個是生成時間戳要精確到秒 2.生成時所要求的URL實際上是前臺頁面的url地址緩存
下面一步一步來作,首先建立jssdk.js 在這個下面用來返回wx.config所須要的信息(具體每一個都啥意思,這個你看官方文檔寫的很明白了https://mp.weixin.qq.com/wiki...),能夠在開發的時候將生成token/ticket都打印出來,在官方提供的工具上面https://mp.weixin.qq.com/debu... 進行測試,比較signature是否是一致安全
完整jssdk.js代碼以下:服務器
var request = require('request'), cache = require('memory-cache'), sha1 = require('sha1') var express = require('express'); var app = express(); app.use('/wx', express.static('static')); app.get('/getsign', function (req, res) { var url = "http://xx.xx.cn/wx/Image.html" console.log(url) var noncestr = "123456", timestamp = Math.floor(Date.now() / 1000), //精確到秒 jsapi_ticket; if (cache.get('ticket')) { jsapi_ticket = cache.get('ticket'); // console.log('1' + 'jsapi_ticket=' + jsapi_ticket + '&noncestr=' + noncestr + '×tamp=' + timestamp + '&url=' + url); obj = { noncestr: noncestr, timestamp: timestamp, url: url, jsapi_ticket: jsapi_ticket, signature: sha1('jsapi_ticket=' + jsapi_ticket + '&noncestr=' + noncestr + '×tamp=' + timestamp + '&url=' + url) }; res.send(obj) } else { request('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appid&secret=secret', function (error, response, body) { if (!error && response.statusCode == 200) { var tokenMap = JSON.parse(body); request('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' + tokenMap.access_token + '&type=jsapi', function (error, resp, json) { if (!error && response.statusCode == 200) { var ticketMap = JSON.parse(json); cache.put('ticket', ticketMap.ticket, (1000 * 60 * 60 * 24)); //加入緩存 // console.log('jsapi_ticket=' + ticketMap.ticket + '&noncestr=' + noncestr + '×tamp=' + timestamp + '&url=' + url); obj = { noncestr: noncestr, timestamp: timestamp, url: url, jsapi_ticket: ticketMap.ticket, signature: sha1('jsapi_ticket=' + ticketMap.ticket + '&noncestr=' + noncestr + '×tamp=' + timestamp + '&url=' + url) } res.send(obj) } }) } }) } }); var server = app.listen(3000, function () { var host = server.address().address; var port = server.address().port; console.log('Example app listening at http://%s:%s', host, port); });
1.都寫完了之後,在瀏覽器上運行Image.html看不到效果,要在手機微信裏面纔有效果,這時候能夠用草料二維碼 https://cli.im/url 一直在用,很好用,你把地址貼過來(http://xx.xx.cn/wx/Image.html),生成一個二維碼,手機微信掃一掃就能夠了微信
2.Image.html上的wx.config中的debug必定要設置爲true,在wx.ready的外面加上app
wx.error(function(res){ console.log(JSON.stringify(res)) })
最後終於看見了 config:ok 心情好複雜,調試過程好艱辛,靠猜