个人文档
  • AI编程Cursor
  • GPT使用笔记
  • npm常用库合集
  • 同步用
  • 小Demo们
  • 工具网站教程集合
  • HTML、CSS 工具方法集合
    • HTML 全局属性
    • css常用功能
    • font-face 字体|子集相关
    • iframe父子页面传值
    • input输入优化
    • loading状态
    • nodejs使用谷歌邮箱发邮件
    • 为 Dom 自定义事件监听
    • 初始html的head标签配置
    • 拼音输入中文汉字的事件监听
    • 文字颜色效果
    • 文档片段范围 Range
    • 移动端开发-rem
    • 等宽字体推荐
    • 网站SEO优化注意点
    • 邮件html模板
  • JS 工具方法集合
    • Axios 简单使用
    • Axios 简单封装
    • Gitbook的安装和使用
    • Github 登录开发
    • HTML转为纯文本
    • JS 中强大的操作符
    • cookie 操作
    • js 动态加载js资源
    • js 常用功能语句
    • js取代trycatch的方法封装
    • js接口下载二进制
    • script 标签的异步属性
    • 判断当前是移动端还是pc端
    • 刷新token队列管理
    • 前端多线程 Web Worker
    • 加密-AES对称加密
    • 加密-node进行rsa加密解密
    • 地区省市区三级联动的地址数据 + 功能
    • 复制插件
    • 开发时环境变量
    • 得到随机图片
    • 数字格式整理集合
    • 数学计算插件
    • 时间格式整理
    • 获取ip地址
    • 获取url传参
    • 进制转换和位运算符
    • 页面隐藏|激活|关闭的监听
  • JS 知识点研究
    • Babel 历史和原理
    • Babel 配置和使用
    • Function 的 apply、call、bind
    • HTTP浏览器缓存粗解
    • Source map 文件还原为源码
    • TS常用技巧
    • js 的加载和模块化
    • js 的新数据类型 Symbol
    • js的代理对象 proxy 和 defineProperty
    • js的原型链 prototype
    • vite 打包体积优化
    • webpack 可视化打包文件大小插件
    • webpack 基础使用配置
    • webpack 版本5的报错
    • yeoman 开发脚手架的工具
    • 同步异步和微任务宏任务
    • 移动端调试---谷歌工具+eruda+vconsole
    • 转换-Blob URL
    • 转换-FileReader
    • 转换-Js文件类型和转换
    • 转换-前端开发的URL的编码和解码
    • 转换-字符串和Base 64的转换
  • Node 和 Npm 相关
    • Node 开发环境配置
    • express + jwt 校验
    • node 常用方法
    • node后台服务器-PM2
    • node基本使用
    • npm 中依赖的版本问题
    • npm 功能使用
    • npm指令说明和其他对比
    • nvm版本管理+自动切换node版本
  • React 学习
    • React Hook
    • React 项目基础开发
    • React.memo 和 React.PureComponent
    • React懒加载进阶
    • useContext Hook
    • useEffect Hook
    • useMemo 和 useCallback - Hook
    • useRef Hook
    • useState Hook
    • 同步修改变量功能封装 useVal for react
    • 轻便的传值组件
  • Rust 语言相关
    • Rust 基本
    • Rust 基础学习
    • Rust 调用 Object-C 的API
    • Tauri 基本使用
    • Tauri 是什么
  • VUE 学习
    • Vue3 使用
    • Vue3使用hook
    • Vue开发小技术点
    • vue路由切换时的动画效果
    • 花式引入组件和资源-打包时拆包减少js体积
  • Web3相关
    • Web3.0开发上-准备和概念理解
    • Web3.0开发下-功能代码示例
    • 以太坊区块链和Web3.0
    • 开发智能合约
  • python
    • pyenv版本管理工具
    • python初始化
    • python基本概念
    • venv虚拟环境
  • 个人其他
    • Steam Deck的基本设置和插件
  • 其他编程相关
    • Git教程和常用命令
    • Java开发-JDK和Maven的安装和卸载
    • Jenkins安装和基本使用
    • Linux系统指令
    • Mac 使用2K屏幕开启缩放
    • Mac 使用VS code打开项目
    • Mac 安装 Homebrew
    • Mac 的终端 shell 与 zsh
    • Mac 软件和插件
    • MacBook使用建议
    • Mac升降级到指定版本的系统
    • Mac安装Zsh
    • Mac安装软件各种提示
    • Mac系统脚本语言 AppleScript 的使用
    • Mac终端代理工具
    • Markdown(md)文档开发-Typora
    • Mysql 的安装和使用
    • Nginx 安装和基础使用
    • Nginx 稍微高深的配置
    • Slate - Api 的文档开发工具
    • Sublime配置
    • Ubuntu的 apt-get 使用
    • VScode配置
    • Windows 软件和插件
    • curl 工具使用
    • github 网站访问优化
    • host 文件
    • inquirer 终端中和用户交互
    • uTools的插件开发教程
    • vim 文本编辑功能
    • 使用 Github Pages 免费部署网站
    • 压缩指令 zip 和 unzip
    • 油猴的安装和开发(Tampermonkey)
    • 阿里云简略使用
  • 微信开发
    • 微信小程序开发
    • 微信开发必读
    • 微信开发提前购买域名
    • 微信手机打开的页面中授权登录
    • 微信扫码登录
    • 微信服务号登录+推送服务提醒
    • 自定义分享卡片-node.js实现
  • 数据结构与算法
    • KMP算法
    • Wildcard字符串分析算法
    • 二叉树
    • 字典树
    • 时间复杂度浅析
    • 算法神器——动态规划
Powered by GitBook
On this page
  • 微信开发-自定义分享卡片-node.js实现
  • 证明后台项目和前端项目时我自己的
  • 开始正式开发

Was this helpful?

  1. 微信开发

自定义分享卡片-node.js实现

title: 微信开发-自定义分享卡片-node.js实现 id: 1509e16d6680d0bdf7ac673981c8ea80 tags: [] date: 2000/01/01 00:00:00 updated: 2023/03/04 19:29:12 isPublic: true --#|[分隔]|#--

微信开发-自定义分享卡片-node.js实现

首先,需要先进行 微信客户端授权登录。

本篇主要讲述,如何在微信中打开自家的页面,在然后在用户分享的时候,能由我们自定义分享出去后,展示的页面卡片中的页面标题、页面描述、页面图片和分享链接。

此功能,具体的来说,是:

  1. 在微信打开自家的页面

  2. 点击右上角微信的功能按钮,出现功能菜单

  3. 点击分享给好友、朋友圈、QQ好友等

  4. 选择对应的好友,发送

  5. 打开对应的好友聊天界面,可以看到,被分享的页面卡片,在展示上和默认的样式有所不同。

仅在样式上就已经有很所不同,此外最关键的,是分享的url也可以自定义。

默认分享的话,你当前页面的url是什么,那么分享出去就是什么,而自定义的情况,则可以自己定义url,有了极大的灵活性,当然也是还有一些限制,但至少,链接的参数是可以完全自定义的,这个后面文章继续介绍。


下面进入代码阶段。

证明后台项目和前端项目时我自己的

首先,上面证明服务是自己的部分,我们需要实现一个接口,我用http://wx.my.com/forWx打的比方,那么为了启用配置,我需要实现/forWx给微信调用,下面是代码:

node的基础环境搭建省略,这里只写接口内部方法了,关键是参数加密拼装

const crypto = require('crypto')  // 引入加密模块
const config = require('./config') // 引入配置文件
// 提供给微信调用
server.get('/forWx', function (req, res) {
  res.header('Access-Control-Allow-Origin', '*')
  // 1.获取微信服务器Get请求的参数 signature、timestamp、nonce、echostr
  let signature = req.query.signature // 微信加密签名
  let timestamp = req.query.timestamp // 时间戳
  let nonce = req.query.nonce // 随机数
  let echostr = req.query.echostr // 随机字符串

  // 2.将token、timestamp、nonce三个参数进行字典序排序,其中token就是设置在微信页面中的那个自定义字符串
  let array = [config.token, timestamp, nonce]
  array.sort()

  // 3.将三个参数字符串拼接成一个字符串进行sha1加密
  let tempStr = array.join('')
  const hashCode = crypto.createHash('sha1') //创建加密类型 
  let resultCode = hashCode.update(tempStr, 'utf8').digest('hex')
  
  //4.开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
  if (resultCode === signature) {
    res.send(echostr)
  } else {
    res.send('mismatch')
  }
})

完成,上面是证明服务器是我的,后面还需要证明前端项目是我的,这个就跳过了,因为太简单,直接下载那个文件,放到自己服务器中,前端项目的index.html同级即可

上面的操作,是只要想进行微信公页面开发,必须要有的步骤,一切的基础。


开始正式开发

首先顺着功能使用流程,顺一下实现此功能的方法:

  • 用户在微信打开页面后,立即或者通过方法触发ajax,把当前url作为参数,请求自己的后台接口。

  • 后台请求微信服务器,发送自己的AppID和AppSecret,得到一个有效期为7200秒的Access_token

  • 后台再次请求微信服务器,发送Access_token,得到一个有效期同样为7200秒的Ticket(如果前端请求自己的时候,Ticket没有过期,就不用这么麻烦请求两次微信服务器了,直接使用即可,Access_token同理)

  • 后台有了可以使用的Ticket,接着,生成如下几个参数,返回给前端:

    • timestamp:当前时间戳

    • url:前端传过来的url

    • jsapi_ticket:获取的Ticket

    • appId:自己的AppID

    • signature:使用sh1加密的noncestr、timestamp、url、jsapi_ticket的字符串

  • 前端终于拿到了返回值,然后初始下微信服务(当然初始化微信服务之前,需要引入微信SDK的js文件),初始化服务,需要用到以上参数,同时,可以配置你要监听的用户操作,比如我们的关键---分享页面!

  • 微信配置执行后,书写配置完成的回调函数,这个回调函数里,可以定义用户分享页面时的页面参数,当此页面被分享出去之后,展示的分享卡片,就是我们定义的内容啦!

  • 当然,不仅仅是分享页面,发朋友圈和其他一些也是可以配置,还有更多的配置项,都可以开始进行了!

下面是前端获取微信授权的方法

// 微信初始化 sdk
let wxInitSdk = function() {
  let myUrl = window.location.href.split('#')[0]
  console.log('我的url: ', myUrl)
  $.ajax({
    url: BASE_URL + '/getsign',
    type: 'post',
    data: {
      url: myUrl,
    },
    success: function(data) {
      console.log(data)
      wx.config({
        debug: false, // 开启调试模式,开发时可以开启
        appId: data.appId, // 必填,公众号的唯一标识 由接口返回
        timestamp: data.timestamp, // 必填,生成签名的时间戳 由接口返回
        nonceStr: data.noncestr, // 必填,生成签名的随机串 由接口返回
        url: data.url, // 必填,生成签名的随机串 由接口返回
        signature: data.signature, // 必填,签名 由接口返回
        jsApiList: [
          'updateAppMessageShareData', // 分享
        ] // 此处填你所用到的方法
      });
      // 方法监听
      wx.ready(function () {
        console.log('初始化成功')
        wx.updateAppMessageShareData({
          title: '咱的标题', // 分享标题
            desc: '咱的描述', // 分享描述
            link: window.location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
            imgUrl: window.location.protocol + '//' + window.location.hostname + '/img.jpg', // 分享图标
            type: "link", // 分享类型,music、video或link,不填默认为link
            dataUrl: "", // 如果type是music或video,则要提供数据链接,默认为空
            success: function () {
              // 用户确认分享后执行的回调函数
              console.log("分享配置完成");
            },
            cancel: function () {
              // 用户取消分享后执行的回调函数
              console.log('分享取消')
            }
         });
      })
      wx.error(function (res) {
        console.log('初始化失败')
        console.log(res)
      })
    },
    error: function(error) {
      console.log('错误')
    }
  })
}

下面是node端的一系列方法

const sha1 = require('sha1')
const config = require('./config') // 引入配置文件

// 临时缓存
const myCache = {
  access_token: {
    setedTime: 0, // 数据设置的时间
    val: undefined, // 数据的值
  },
  jsapi_ticket: {
    setedTime: 0, // 数据设置的时间
    val: undefined, // 数据的值
  },
}

// 获取 access_token
const getAccess_token = () => {
  // access_token 未过期
  if (myCache.access_token.val && (Math.floor(Date.now()) - myCache.access_token.setedTime) / 1000 < 7100) {
    return Promise.resolve(myCache.access_token.val)
  } else { // access_token 过期了
    return new Promise((resolve, reject) => {
      request(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${config.appId}&secret=${config.appSecret}`, function (error, response, body) {
        if (!error && response.statusCode == 200) {
          let tokenMap = JSON.parse(body)
          // 缓存 access_token
          myCache.access_token.setedTime = Math.floor(Date.now())
          myCache.access_token.val = tokenMap.access_token
          resolve(tokenMap.access_token)
        } else {
          reject(error)
        }
      })
    })
  }
}

// 获取 Ticket
const getJsapi_ticket = () => {
  // 缓存的签名尚未过期 --- 微信规定过期时间为7200秒,这里自己设置7100秒,留100秒的延迟
  if (myCache.jsapi_ticket.val && (Math.floor(Date.now()) - myCache.jsapi_ticket.setedTime) / 1000 < 7100) {
    return Promise.resolve(myCache.jsapi_ticket.val)
  } else { // 已过期,重新获取
    return new Promise((resolve, reject) => {
      // 先获取 token
      utils.getAccess_token().then(access_token => {
        request('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' + access_token + '&type=jsapi', function (error, resp, json) {
          if (!error && resp.statusCode == 200) {
            let ticketMap = JSON.parse(json)
            // 缓存 ticket
            myCache.jsapi_ticket.setedTime = Math.floor(Date.now())
            myCache.jsapi_ticket.val = ticketMap.ticket
            resolve(ticketMap.ticket)
          } else {
            reject(error)
          }
        })
      }).catch(error => reject(error))
    })
  }
}

// 我自己的前端调用,获取微信签名
server.post('/getsign', (req, res) => {
  try {
    params = req.body
    if (!params && !params.url) return res.send('please set url of page')
    let url = params.url
    // 获取 ticket
    getJsapi_ticket().then(jsapi_ticket => {
      let num = Math.random()
      let noncestr = num.toString(32).substr(3, 20) // 随机字符串
      let timestamp = Math.floor(Date.now() / 1000) //精确到秒
      let obj = {
        noncestr,
        timestamp,
        url,
        appId: config.appId,
        jsapi_ticket,
        signature: sha1('jsapi_ticket=' + jsapi_ticket + '&noncestr=' + noncestr + '&timestamp=' + timestamp + '&url=' + url)
      }

      res.send(obj)
    }).catch(error => {
      res.send(error)
    })
  } catch (error) {
    res.send(error)
  }
})

整体功能实现的步骤和具体代码如上,请酌情参考。

Previous微信服务号登录+推送服务提醒Next数据结构与算法

Last updated 3 months ago

Was this helpful?