微信公众号之获取ticket

专栏目录请点击

简介

  1. 我们可以观看官方的简介 点击
  2. 也就是说我们通过sdk可以得到更多的开发能力,比如拍照、选图、语音、位置等手机系统的能力,此外还可以使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
  3. 我们在调用js-sdk的时候,需要使用临时票据jsapi_ticket,他的有效期是7200秒,且调用的次数非常有限,所以我们尽量把它缓存下来
  4. 在获取jsapi_ticket的时候,我们还是需要access_token,获取jsapi_ticket的接口为https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

开发

获取的方法

  • 因为当前的方法需要使用access_token,我们把它写到WeChat这个类下,并模仿access_token获取的步骤来写

接口管理

const prefix = "https://api.weixin.qq.com/cgi-bin/"

module.exports = {
    ticket:`${prefix}ticket/getticket?type=jsapi`
}

获取方法

我们模仿获取access_token的方法,在WeChat类中写以下几个方法

// 获取jsapi_ticket的方法
getTicket() {
    // 因为需要异步获取,这里返回promise
    return new Promise(async(resolve,reject) => {
        const data = await this.fetchAccessToken()
        console.log("data",data);
        const url = `${api.ticket}&access_token=${data.access_token}`
        console.log(url)
        rp({ method: "GET", url, json: true }).then(res => {
            // 格式化
            const {ticket,expires_in} = res
            console.log(res)
            resolve({
                ticket,
                ticket_expires_in:Date.now() + (expires_in -300) * 1000
            })
        }).catch(err => {
            reject(err)
        })

    })

}
// 保存jsapi_ticket的方法
saveTicket(ticket) {
    const ticket_str = JSON.stringify(ticket) // 转化为字符串,不然保存的就是[object object]
    // 保存到本地accress_token.txt文件中,因为writeFile是一个异步方法,所以我们返回一个promise
    return new Promise((resolve, reject) => {
        writeFile("./ticket.txt", ticket_str, err => {
            if (!err) {
                resolve()
            } else {
                reject(err)
            }
        })
    })

}
// 读取access_token的方法
readTicket() {
    return new Promise((resolve, reject) => {
        readFile("./ticket.txt", (err, data) => {
            if (!err) {
                // 转化为js对象
                data = data.toString()
                data = JSON.parse(data)
                resolve(data)
            } else {
                reject(err)
            }
        })
    })
}
// 验证token是否有效的方法
isValidTicket(data) {
    // data 为读取文件
    if (!data || !data.ticket || !data.ticket_expires_in) return false
    return data.ticket_expires_in > Date.now()
}

fetchTicket() {
    // 获取一次后,如果有直接返回
    if (this.ticket && this.ticket_expires_in && this.isValidTicket(this)) {
        return Promise.resolve({ ticket: this.ticket, ticket_expires_in: this.ticket_expires_in })
    }

    return this.readTicket()
        .then(async res => {
            // 判断是否过期
            if (this.isValidTicket(res)) {
                // 没有过期直接返回
                return Promise.resolve(res)
            } else {
                // 过期调用接口请求
                const data = await this.getTicket()
                // 保存
                this.saveTicket(data)
                // 返回
                return Promise.resolve(data)
            }
        })
        .catch(async err => {
            // 本地文件没有保存
            const data = await this.getTicket()
            // 保存
            this.saveTicket(data)
            // 返回
            return Promise.resolve(data)
        })
        .then(res => {
            // 这里主要是将相关信息放到实例对象上
            const { expires_in, ticket } = res
            this.ticket_expires_in = expires_in
            this.ticket = ticket
            return Promise.resolve(res)
        })
}
对于代码的解释
  1. 这里我们模仿获取acesstoken的方法一共写了getTicketsaveTicketreadTicketisValidTicketfetchTicket这5个方法,其中的逻辑比较简单
  2. 但是我们发现读文件和写文件代码重复的较多,这里我们可以封装一下文件的读写

读文件和写文件

  • 我们把它放到了utils.js文件夹下,并写上了如下的方法
const { resolve } = require("path")
const { readFile, writeFile } = require("fs")

module.exports = {
	//...
    writeFileAsync(data, fileName) {
        const filePath = resolve(__dirname, fileName) // 传入绝对路径
        const data_str = JSON.stringify(data)
        return new Promise((resolve, reject) => {
            writeFile(filePath, data_str, err => {
                if (!err) {
                    resolve()
                } else {
                    reject(err)
                }
            })
        })
    },
    readFileAsync(fileName) {
        const filePath = resolve(__dirname, fileName) // 传入绝对路径,__dirname:获取当前文件所在的路径
        return new Promise((resolve, reject) => {
            readFile(filePath, (err, data) => {
                if (!err) {
                    // 转化为js对象
                    data = data.toString()
                    data = JSON.parse(data)
                    resolve(data)
                } else {
                    reject(err)
                }
            })
        })
    }
}

在项目中的使用

const { readFileAsync, writeFileAsync } = require("../libs/utils")

// 保存jsapi_ticket的方法
saveTicket(ticket) {
    return writeFileAsync(ticket,"ticket.txt")
}
// 读取access_token的方法
readTicket() {
    return readFileAsync("ticket.txt")
}

对于代码的解释

  1. 我们想把保存ticket的文件保存在utils.js的文件夹下,所以就写了__dirname来获取当前的文件
  2. 我们可以运行测试一下,就会发现我们获取的ticket.txt就放到了utils.js所在的文件夹下
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值