• 微信公众号之获取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`
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    获取方法

    我们模仿获取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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    对于代码的解释
    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)
                    }
                })
            })
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    在项目中的使用

    const { readFileAsync, writeFileAsync } = require("../libs/utils")
    
    // 保存jsapi_ticket的方法
    saveTicket(ticket) {
        return writeFileAsync(ticket,"ticket.txt")
    }
    // 读取access_token的方法
    readTicket() {
        return readFileAsync("ticket.txt")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    对于代码的解释

    1. 我们想把保存ticket的文件保存在utils.js的文件夹下,所以就写了__dirname来获取当前的文件
    2. 我们可以运行测试一下,就会发现我们获取的ticket.txt就放到了utils.js所在的文件夹下
  • 相关阅读:
    分布式一致性算法 Raft
    LLM——langchain 与阿里 DashScop (通义千问大模型) 和 DashVector(向量数据库) 结合使用总结
    Java容器家族整理+源码分析图!
    使用tailwindcss来构建以及引入外部组件
    keyboard库,keyboard.press(”a“)没有效果的可能原因
    解决建筑材料采购难题,数字化采购平台标准化接口服务助力企业采购协同更便捷
    算法设计与分析100例子(C语言版)
    【附源码】计算机毕业设计SSM同城互助平台
    如何在电脑上玩“胆小菇之梦”
    数学建模笔记-第三讲-插值
  • 原文地址:https://blog.csdn.net/youhebuke225/article/details/126221069