Loading

JS-SDK 配置,实现微信分享功能

官方文档https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html

在使用微信分享功能之前,需要进行如下配置,参考官方文档

1. 绑定域名

此处看官方文档

2. 引入JS文件

此处看官方文档

3. 通过config接口注入权限验证配置

这里进行步骤分解

3.1 调用后端签名接口

此处签名需要前端传递当前页面路由给后端进行签名

noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com?params=value

3.2 调用签名接口成功之后,使用wx.config配置

wx.config({
  debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  appId: '', // 必填,公众号的唯一标识 
  timestamp: , // 必填,生成签名的时间戳 //可让后端返回
  nonceStr: '', // 必填,生成签名的随机串
  signature: '',// 必填,签名
  jsApiList: [] // 必填,需要使用的JS接口列表
});

为了前后端字段统一,appId timestamp nonceStr signature 这4个字段由后端统一返回

3.3 js-sdk配置完之后,使用updateAppMessageShareData方法实现微信分享功能

wx.ready(function () {   //需在用户可能点击分享按钮前就先调用
  wx.updateAppMessageShareData({ 
    title: '', // 分享标题
    desc: '', // 分享描述
    link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致,地址无需编码
    imgUrl: '', // 分享图标,得使用网络地址
    success: function () {
      // 设置成功
    }
  })
});

到目前为止算是配置完成了,下面附上使用next.js进行签名的接口和对js-sdk封装的hooks

生成随机字符串

/** 随机字符串 **/
export const uuid = () => {
  return Math.random().toString(36).substring(2)
}

next.js进行签名的接口

// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'
import { createHash } from 'crypto'
import { uuid } from '@/utils'

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse<Record<string, any>>
) {
  const method = req.method
  if (method == 'POST') {
    const noncestr = uuid()
    const timestamp = Math.floor(Date.now() / 1000)
    const appId = process.env.APPID
    const secret = process.env.SECRET
    let { url } = req.body || {}
    if (!url) return res.json({ code: 500, message: 'url不能为空' })
    const accessToken = await fetch(
      `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${secret}`
    ).then(async (response) => {
      const data = await response.json()
      return data.access_token
    })
    console.log({ accessToken })
    const ticket = await fetch(
      `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${accessToken}&type=jsapi`
    ).then(async (response) => {
      const data = await response.json()
      return data.ticket
    })
    console.log({ ticket })
    // 要加密的数据
    const dataToHash = `jsapi_ticket=${ticket}&noncestr=${noncestr}&timestamp=${timestamp}&url=${url}`
    // 创建 SHA1 哈希对象
    const sha1Hash = createHash('sha1')
    // 更新哈希对象的内容
    sha1Hash.update(dataToHash)
    // 计算哈希值
    const hashedData = sha1Hash.digest('hex') // 'hex' 表示输出为十六进制
    console.log(dataToHash)
    return res.json({
      data: {
        noncestr,
        timestamp,
        url,
        appId,
        signature: hashedData
      },
      code: 200
    })
  }
}

react对js-sdk分享功能封装的hooks

import { useEffect } from 'react'

/** 生成签名 */
const generateSignature = (
  data: Record<string, any>
): Promise<Record<string, any>> => {
  return new Promise((resolve, reject) => {
    fetch('/api/weixin', {
      method: 'POST',
      body: JSON.stringify({
        url: data.url
      }),
      headers: {
        'Content-Type': 'application/json'
      }
    }).then(async (response) => {
      const data = await response.json()
      if (data.code == 200) {
        resolve(data.data)
      } else {
        reject(data)
      }
    })
  })
}

type JweixinType = {
  jsApiList?: string[]
  ready: (wx: Record<string, any>, url: string) => void
}
const useJweixin = (data: JweixinType) => {
  if (!process.browser) {
    return null
  }
  if (!window.device.weixin) {
    return null
  }
  const url = window.location.href
  useEffect(() => {
    generateSignature({
      url: url.split('#')[0]
    }).then((result) => {
      const { timestamp, noncestr, signature, appId } = result
      window.wx.config({
        debug: process.env.NODE_ENV !== 'production', // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId, // 必填,公众号的唯一标识
        timestamp, // 必填,生成签名的时间戳
        nonceStr: noncestr, // 必填,生成签名的随机串
        signature, // 必填,签名
        jsApiList: data.jsApiList || ['updateAppMessageShareData'] // 必填,需要使用的JS接口列表
      })
      window.wx.ready(() => {
        data.ready(window.wx, url)
      })
    })
  }, [])
}

export default useJweixin

 使用方式

  useJweixin({
    ready: (wx, url) => {
      wx.updateAppMessageShareData({
        title: 'xx',
        desc: 'xx',
        link: window.location.href,
        imgUrl: 'https://xx/wxShareThumb.png'
      })
    }
  })

  

posted @ 2024-02-20 10:56  冯叶青  阅读(270)  评论(0编辑  收藏  举报