H5接入微信JS-SDK踩坑指南,自定义微信分享(包含Vue和React接入)

5,905 阅读5分钟

最近项目中需要定制微信分享文案和图片,发现官方文档中描写的不是很全面,导致踩坑连连,翻了下其他大神的文章发现大多是基于Vue的,奈何我们的项目是React开发,所以这里总结一下VueReact的完整接入指南,希望对大家有所帮助。

前期准备

Step 1. 申请公众号

这一步就不多说。

Step 2. 配置安全域名

根据微信文档指示,在接入JS-SDK前,我们需要先在公众号上配置好安全域名,入口“公众号设置” -> “功能设置” -> “JS接口安全域名”

配置安全域名官方描述:

设置JS接口安全域名后,公众号开发者可在该域名下调用微信开放的JS接口。

注意事项:

1、可填写五个域名或路径(例:wx.qq.com或wx.qq.com/mp),需使用字母、数字及“-”的组合,不支持IP地址、端口号及短链域名。

2、填写的域名须通过ICP备案的验证。

3、 将文件MP_verify_wMrzRtdI1aeoSMtw.txt(点击下载)上传至填写域名或路径指向的web服务器(或虚拟主机)的目录(若填写域名,将文件放置在域名根目录下,例如wx.qq.com/MP_verify_wMrzRtdI1aeoSMtw.txt;若填写路径,将文件放置在路径目录下,例如wx.qq.com/mp/MP_verify_wMrzRtdI1aeoSMtw.txt),并确保可以访问。

这里我们需要关注两个点,一个是配置的域名需要有ICP备案,另一个是我们需要下载验证文件放在指定位置。

常见问题

  1. 在配置安全域名的时候,会出现内容与下载文件不符,请检查文件内容或重新上传原始文件错误提示?
1. 检查访问填写路径是否可以打开文件(尤其是使用无痕浏览器确认下有没有权限拦截)
2. waf ..web防火墙,查看日志是否有阻挡
2. 如果域名有上CDN即需要预热并用全国节点访问一次,让其刷新内容到CDN节点(可以 https://www.17ce.com/ 打开这个网站,输入认证的完整域名即http(s)://域名+MP_verify_xxxx.txt,然后点检测一下)

接入JS-SDK

Setp 1. 引入JS

安装JS-SDK:

npm install weixin-js-sdk

安装后引入:

import wx from 'weixin-js-sdk'

Step 2. config接口注入权限验证配置

官方文档中这样描述:

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)

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

因为wx.config根据url变化需要重新配置,所以可以对config配置做封装,放在全局使用:

// vue版本
export function initWechatWebview() {
  const timestamp = Date.now();
  const nonceStr = randomString(16);
  const url = window.location.href.split('#')[0]
  try {
    // 后端请求获取签名
    const { data } = await someFunction();
    wx.config({
      debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
      appId: '', // 必填,公众号的唯一标识
      timestamp, // 必填,生成签名的时间戳
      nonceStr, // 必填,生成签名的随机串
      signature: data, // 必填,签名
      jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData'], // 必填,需要使用的JS接口列表
    });
  } catch (e) {
    console.log(e);
  }
}s
Vue.prototype.wxconfig = initWechatWebview;

// react版本
// 封装一个路由组件
interface match<Params extends { [K in keyof Params]?: string } = {}> {
  params: Params;
  isExact: boolean;
  path: string;
  url: string;
}
interface IProps extends RouteProps {
  location?: Location;
  history?: History;
}

export function CustomRoute(props: IProps) {
  const { path = '/' } = props;
  const currentRoute = routes.filter(r => r.path === path)[0];
  const location = useLocation();
  const { pathname } = location;
  const page =
    typeof currentRoute.logPageName === 'string'
      ? currentRoute.logPageName
      : currentRoute.logPageName[pathname];

  async function initWechatWebview() {
    const timestamp = Date.now();
    const nonceStr = randomString(16);
    const url = window.location.href;
    try {
      // 后端请求获取签名
      const { data } = await someFunction();
      wx.config({
        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: '', // 必填,公众号的唯一标识
        timestamp, // 必填,生成签名的时间戳
        nonceStr, // 必填,生成签名的随机串
        signature: data, // 必填,签名
        jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData'], // 必填,需要使用的JS接口列表
      });
    } catch (e) {
      console.log(e);
    }
  }

  useEffect(() => {
    initWechatWebview();
  }, [page]);

  return <Route {...props} />;
}

常见问题

  1. 这里的签名出于安全一般由后端生成,很多文章中timestampnonceStr也是由后端生成,这个其实也可以前端生成,只要保证签名算法使用的是同一套就可以了。
  2. 在ios的spa应用中,会取首次进入的url生成签名,无论路由切换到哪个页面,实际真正有效的的签名URL是【第一次进入应用时的URL】,所以可以考虑缓存首次进入的url

Step 3. 分享接口使用

在配置好上面的基础信息后,即可在需要的页面调用使用接口,详细的接口说明可见 微信官方文档

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

总结

接入微信JS-SDK避开上述的一些常见问题,基本还是比较顺畅的,大多数接口微信文档中描述的也比较详细,希望这篇文章对大家有所帮助。