接入微信JSSDK流程圖

image.png
1、準備工作
1-1、前端:Vue
1、npm i weixin-js-sdk -S //安裝微信js-sdk
2、npm i axios -S //安裝接口請求模塊
1-2、后端:Koa
這里我們先規(guī)定Koa端口啟動在8050上
后面內(nèi)網(wǎng)映射需要使用該端口
1、npm i axios -S //安裝接口請求模塊用自帶的http也行
2、npm i sha1 -D //安裝加密模塊
3、npm i node-cache -D //安裝緩存模塊
4、npm i koa-bodyparser koa-router koa
1-3、內(nèi)網(wǎng)映射工具Ngrok
Ngrok地址PS:絕對不是打廣告,使用方法開官方文檔
為什么要用內(nèi)網(wǎng)映射?
因為我們目前是在本地開發(fā),我們使用測試好進行開發(fā)
配置Ngrok,進入他的控制臺購買一臺免費的服務(wù)器

image.png

image.png

image.png
1-4、申請微信測試號
測試號申請地址
有的同學(xué)可能會問怎么配置?,別急我們寫編寫我們的Koa代碼,我們這里會拿到測試號提供的
appId、appsecret
2、Koa服務(wù)端的編寫
index.js
const koa = require('koa');
const app = new koa();
const routesr = require('./routes');
const bodyParser = require('koa-bodyparser');
app.use(bodyParser())
app.use(routesr.routes())
app.listen(8050,()=>{
console.log('server in port 8050')
})
創(chuàng)建util文件夾創(chuàng)建config.js
module.exports = {
token : "12qq",//我們剛剛微信測試號頁面上準備填的token
appid : "*****",//微信測試號上的APPID
appsecret : "*****",//微信測試號上的appsecret
getAccessToken : "https://api.weixin.qq.com/cgi-bin/token",//這個是微信官方請求accesstoken地址
getjstick : "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token="http://這個是官方獲取tick地址
}
創(chuàng)建routes文件夾并且創(chuàng)建index.js路由文件
我們先寫微信測試號的接口配置信息
const router = require('koa-router')();
const sha1 = require('sha1')
//接口信息配置訪問的接口
//即微信測試頁面的 接口配置信息
router.get('/appconfig',async ctx=>{
const token = config.token;
const signature = ctx.request.query.signature
const nonce = ctx.request.query.nonce
const timestamp = ctx.request.query.timestamp
const echostr = ctx.request.query.echostr
let str = [token, timestamp, nonce].sort().join('')
const sha = sha1(str)
ctx.body = sha === signature ? echostr + '' : 'failed'
})
2-2、配置測試號接口信息
1、啟動koa服務(wù)
2、使用Ngrok啟動內(nèi)網(wǎng)映射,啟動方法見他的文檔
當上面兩步做完之后,我們打開測試號頁面

image.png
2-3、編寫緩存文件
在util文件夾中創(chuàng)建cache.js文件
為什么要用緩存?
image.png
const NodeCache = require("node-cache");
const myCache = new NodeCache({
stdTTL: 7200, // 緩存過期時間
checkperiod: 120 // 定期檢查時間
});
// 設(shè)置緩存
const setCache = async (key, value)=> {
// 設(shè)置緩存
let values = await myCache.set(key, value);
return values;
};
// 獲取緩存
const getCache = async key => {
// 讀取緩存
let result = await myCache.get(key);
return result;
};
module.exports = {
setCache,
getCache
}
2-4獲取微信的access_token
在根路徑下創(chuàng)建controller文件夾并且穿件getAccToken.js
// 獲取 access_token
const config = require('../util/config'); // 配置數(shù)據(jù)
const axios = require('axios'); // 請求api
// (設(shè)置 | 獲取)緩存方法
const cache = require('../config/cache');
module.exports = getAccessToken = async () => {
const fetchUrl = `${config.getAccessToken}?grant_type=client_credential&appid=${config.appid}&secret=${config.appsecret}`;
// console.log(fetchUrl, config);
var token = await cache.getCache('access_token');
if(token){
return {
"access_token" : token,
"from" : "cache"
};
}else{
let res = await axios.get(fetchUrl);
let data = res.data;
if(data.access_token){
cache.setCache('access_token', data.access_token)
}
return {
"access_token" : data.access_token,
"from" : "axios"
};
}
};
2-5獲取微信的jstick
在根路徑下創(chuàng)建controller文件夾并且穿件getJsTick.js
const axios = require('axios'); // 請求api
const config = require('../util/config'); // 配置數(shù)據(jù)
const cache = require('../util/cache');
module.exports = get_jsapi_ticket = async access_token => {
const fetchUrl = config.getjstick + access_token;
const cacheName = "jsapi_ticket";
var ticket = await cache.getCache(cacheName);
if(ticket){
return {
ticket: ticket,
from: 'cache'
}
}else{
var result = await axios.get(fetchUrl)
let data = result.data;
if(data.ticket){
cache.setCache(cacheName, data.ticket)
}
return {
"ticket" : data.ticket,
"from" : "axios"
};
}
}
2-6獲取簽名
在controller文件夾并且穿件setSign.js
const sha1 = require("sha1")
const config = require("../util/config")
var createNonceStr = function () {
return Math.random().toString(36).substr(2, 15);
};
var createTimestamp = function () {
return parseInt(new Date().getTime() / 1000) + '';
};
var raw = function (args) {
var keys = Object.keys(args);
keys = keys.sort()
var newArgs = {};
keys.forEach(function (key) {
newArgs[key.toLowerCase()] = args[key];
});
var string = '';
for (var k in newArgs) {
string += '&' + k + '=' + newArgs[k];
}
string = string.substr(1);
return string;
};
/**
* @synopsis 簽名算法
*
* @param jsapi_ticket 用于簽名的 jsapi_ticket
* @param url 用于簽名的 url ,注意必須動態(tài)獲取,不能 hardcode
*
* @returns
*/
var sign = function (jsapi_ticket, url) {
var ret = {
jsapi_ticket: jsapi_ticket,
nonceStr: createNonceStr(),
timestamp: createTimestamp(),
url: url
};
var string = raw(ret);
var shaObj = sha1(string);
ret.signature = shaObj;
ret.appId = config.appid;
return ret;
};
module.exports = sign;
2-7編寫訪問路由
當以上文件都完成之后我們就差最后一步,開啟路由訪問獲取簽名
我們在routes文件夾中的index繼續(xù)編寫
//加上
const accessToken = require('../controller/getAccToken.js');
const jsTick = require('../controller/getJsTick.js');
const setSign= require('../controller/setSign.js');
router.get('/get/sign',async ctx=>{
const params = {};
var token = await accessToken();
var tick = await jsTick(token.access_token);
params.url = ctx.query.url;//注意前端需要傳url參數(shù)
params.ticket = tick;
var qm = await setSign(params.ticket.ticket,params.url);
ctx.body = qm;
})
以上工作都做完我們可以嘗試訪問

image.png
結(jié)束服務(wù)端內(nèi)容
2-8測試簽名算法是否正確
我們可以進行測試簽名算法是否正確
進入微信公眾平臺接口調(diào)試工具
輸入我們的參數(shù)即可
3、編寫前端Vue代碼
創(chuàng)建判斷平臺的工具文件
// ssr support
export const inBrowser = typeof window !== 'undefined'
export const ua = inBrowser && navigator.userAgent.toLowerCase()
export const isWeChatDevTools = ua && ua.match(/MicroMessenger/i) == "micromessenger";
export const isAndroid = ua && ua.indexOf('android') > 0
mounted(){
// 只要訪問的是微信瀏覽器 我們就請求接口
if(isWeChatDevTools ) this._Share()
},
async _Share(){
let self = this;
let res = await axios.get("/api/get/sign?url="+location.href.split('#')[0])
if(res.data.Code != 0) return
let data = res.data.data;
wx.config({
debug: false, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會通過log打出,僅在pc端時才會打印。
appId: data.appId, // 必填,公眾號的唯一標識
timestamp: data.timestamp, // 必填,生成簽名的時間戳
nonceStr: data.nonceStr, // 必填,生成簽名的隨機串
signature: data.signature, // 必填,簽名
jsApiList: ["updateAppMessageShareData", "updateTimelineShareData"] // 必填,需要使用的JS接口列表
});
wx.ready(function() {
self.wxShareTimeline();
});
},
wxShareTimeline(){
//分享至朋友/QQ好友
wx.updateAppMessageShareData({
title: ShareConfig.title, // 分享標題
desc: ShareConfig.desc, // 分享描述
link: location.href.split('#')[0], // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應(yīng)的公眾號JS安全域名一致
imgUrl: ShareConfig.imgUrl
})
//分享至QQ空間/朋友圈
wx.updateTimelineShareData({
title: ShareConfig.title, // 分享標題
desc: ShareConfig.desc, // 分享描述
imgUrl: ShareConfig.imgUrl
})
}
4、測試代碼的可用性
掃描測試號頁面的二維碼進入測試公眾號里面

image.png
然后我們進行訪問Vue的訪問域名 記住該地址一定是你在測試號配置的js安全域名的地址然后我們分享
