1. 根目錄下創建config文件夾,結構如下
│─ config
│ │─ config.js
│ │─ fsObj.js
│ │─ setSdk.js
│ └─ json
│ │─ access_token.json
└─ └─ jsapi_ticket.json
2. config.js 中的配置信息
module.exports = {
appId: '', // 你公眾號的id
appSecret: '', // 你公眾號的appSecret
}
3. fsObj.js 中的代碼
const fs = require('fs')
const https = require('https') // 發起請求獲取token和ticket
const config = require('./config')
// 根據參數寫入token或者ticket,並返回寫入結果
const write = (file, ca) => {
// 獲取token並寫入
switch (file) {
case 'token':
httpsGet('access_token', `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${config.appId}&secret=${config.appSecret}`, ca)
break;
case 'ticket':
read('token', res => {
httpsGet('jsapi_ticket', `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${res.access_token.access_token}&type=jsapi`, ca)
})
break;
}
}
const httpsGet = (filesName, getUrl, ca) => {
// 請求token和ticket
https.get(
getUrl,
function (data) {
var str = "";
data.on("data", function (chunk) {
str += chunk; //監聽數據響應,拼接數據片段
})
data.on("end", function () {
let times = Date.parse(new Date())
let result = `{"${filesName}":${str.toString()},"times":${times + 7200 * 1000}}`
// 判斷 jsapi_ticket 是否獲取成功, 成功后寫入,不成功側打印 jsapi_ticket 獲取失敗
if (filesName === 'jsapi_ticket') {
let resultObj = JSON.parse(result)
if (resultObj.jsapi_ticket.errmsg !== 'ok') {
// 沒有獲取成功
console.log(`jsapi_ticket 獲取失敗,寫入失敗, 原因:token錯誤,或其他錯誤`)
return
}
}
// console.log(result)
const writeStream = fs.createWriteStream(`./config/json/${filesName}.json`);
//寫入數據,指定數據的編碼格式
writeStream.write(result, 'utf8');
//標記寫入完成(寫入完成后會廣播一個finish事件)
writeStream.end();
//接收finish事件
writeStream.on('finish', () => {
console.log('寫入完成');
ca(JSON.parse(result)) // 寫入完成后返回結構
});
//寫入失敗
writeStream.on('error', () => {
console.log('寫入失敗');
})
})
})
}
const read = (file, ca) => {
let files = ['access_token', 'jsapi_ticket']
let filesName = files[0]
switch (file) {
case 'token':
filesName = files[0]
break;
case 'ticket':
filesName = files[1]
break;
}
// 查詢數據
let readStream = fs.createReadStream(`./config/json/${filesName}.json`);
let str = ''
//接收讀取到的數據
readStream.on('data', (chunk) => {
str += chunk;
});
//讀取完成后觸發
readStream.on('end', (chunk) => {
ca(JSON.parse(str)) // 查詢完成后返回查詢結果
});
//讀取失敗
readStream.on('error', (error) => {
console.log(error);
});
}
// 過期自動寫入
const checkToken = checkCa => {
read('token', res => {
let times = Date.parse(new Date())
if (times < res.times) {
console.log("沒過期")
checkCa()
}
if (times > res.times) {
console.log("過期了")
// 過期了
// 寫入token
write('token', token_res => {
console.log(`寫入token成功 ---${token_res}`);
// 寫入token完成后寫入ticket
write('ticket', res => {
console.log(`寫入ticket成功 --- ${res}`)
checkCa()
})
})
}
})
}
module.exports = {
read, // 讀取數據
checkToken // 檢查數據是否過期,如果過期側獲取新數據並寫入
}
4. setSdk.js 代碼如下:
const config = require('./config')
const {
read,
checkToken
} = require('./fsObj')
const sha1 = require('sha1')
// 生成字符串
const getStr = () => {
return Math.random().toString(36).substr(2, 15)
}
// 時間戳
const getTimestamp = () => {
return parseInt(new Date().getTime() / 1000) + ''
}
// 排序
const raw = 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
}
// 返回數據,只需要傳入一個前端提交過來的網頁url即可獲得處理好的新數據
module.exports = url => {
return new Promise((resolve, reject) => {
// 先檢查數據是否過期,
checkToken(() => {
//檢查完成后再去獲取數據,並返回給前端
read('ticket', res => {
// 獲取到的數據以key value的形式放入對象中
let ret = {
jsapi_ticket: res.jsapi_ticket.ticket,
nonceStr: getStr(),
timestamp: getTimestamp(),
url
}
// 排序
let string1 = raw(ret)
// 加密
let sha1Str = sha1(string1)
// 返回處理好的數據
resolve({
appId: config.appId,
timestamp: ret.timestamp,
nonceStr: ret.nonceStr,
signature: sha1Str
})
})
})
})
}
5. 太長了請移步下一篇文章:
node生成簽名使用
