Vue+Koa使用微信分享等功能

接入微信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安全域名的地址然后我們分享

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容