超详细的微信分享网页链接配置教程(JS-SDK的使用)

7,422 阅读12分钟

前言

当我们有一个链接想要分享给微信朋友时,有以下几种方法:

  1. 直接复制粘贴。朋友收到的是一个链接字符串,十分的难看。

  2. 从其他应用分享到微信:使用手机浏览器或QQ等其他应用打开连接后分享到微信,会发现分享链接会有标题、描述、缩略图。具体展示跟打开的应用有关,如QQ打开的链接标题为网站的title、描述为链接字符串、缩略图为网站的部分截图。

    image.png

  3. 微信内分享:使用微信扫一个二维码进入链接,再通过微信分享给朋友,会发现默认情况下分享的标题为网站标题、描述为链接字符串,缩略图为一个svg。

    image.png

本文主要讨论的是第三种情况,当在微信内进行分享(扫码分享)时,微信提供了 js-sdk 对分享链接进行配置,可以自定义分享链接的标题、描述和缩略图,接下来我们参考 JS-SDK说明文档 一步步的讲解如何配置。

💡 官方文档:JS-SDK说明文档

前期准备

1. 注册公众号

前往 微信公众号平台 注册一个公众号(订阅号或小程序都可以,因为我们要使用的是微信sdk的分享接口,该接口需要进行微信认证,只用企业账号才可以进行微信认证,所以注册的一定要是企业账号!!!)。

2. 登录到微信公众号平台进行一些必要配置

a. 点击左侧菜单栏的”设置与开发“ → ”基本配置“ 可以生成 开发者ID(AppID)开发者密码(AppSecret),注意 AppSecret 生成后要自己保存好,之后在微信公众号平台是不会再显示这个密码的,当然如果忘了还是可以重置掉的。(这个 appsecret 主要用于获取Access token,后面会讲到)。

b. 进入到”设置与开发“ → ”公众号配置“ → ”功能设置“ → “JS接口安全域名”的设置页面添加需要调用 js-sdk 的域名,域名要求看下图的注意事项(注意一个月只能修改5次)。

image.png

3. 获取AccessToken

使用上面的 appidappsceret 调用以下接口,请求成功会得到access_token和一个过期时间{"access_token":"ACCESS_TOKEN","expires_in":7200}

 GET <https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET>

建议公众号开发者使用中控服务器统一获取和刷新 access_token,其他业务逻辑服务器所使用的 access_token 均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致 access_token 覆盖而影响业务;过期时间目前是7200秒之内的值,中控服务器需要根据这个有效时间提前去刷新access_token。

4. 添加服务器到白名单

直接调用上面的 获取accessToken接口会发现接口调用失败,这是因为没有配置白名单。

公众号和小程序均可以使用AppID和AppSecret调用获取accessToken接口来获取access_token。调用接口时,请登录“微信公众平台-设置与开发-基本配置”提前将服务器IP地址添加到IP白名单中,点击查看设置方法,否则将无法调用成功。小程序无需配置IP白名单。

image.png

如果要使用 Postman来测试接口,如获取 Access Token接口,要将 运行Postman的电脑的 IP 加入到白名单中,否则无法调用成功。

5. 查看自己的公众号是否有接口的使用权限

进入”设置与开发” → ”接口权限“ 页面查看要使用的接口是否有权限。

由于我们要配置微信的分享链接展示,所以我们要使用到“分享接口”

image.png

我们发现“分享接口”需要通过”微信认证“才可以!而且只有企业账号才可以开通微信认证!!!

image.png

开发配置

1. 引入js文件

方法一: 直接在html中引入js文件,用 window.wx 获取到 wx 对象

  • 在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js

  • 如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)。

  • 由于我使用的是 react 框架,直接在 html 文件中引入该 js 文件

    // html
    <script
           src="<http://res.wx.qq.com/open/js/jweixin-1.6.0.js>"
           type="text/javascript"
    ></script>
    
    // js
    const wx = window.wx
    

方法二: 使用 AMD/CMD 标准模块加载方法加载

  • 直接使用weixin-js-sdk

    import wx from 'weixin-js-sdk'
    

注意:以上方法二选一,在 html 中引入了 js 使用 weixin-js-sdk 拿到的 wx 会是 undefined

2. 生成签名(建议后端提供一个接口)

  • 获取 jsapi_ticket

    • 使用上面获取到的 AccessToken 请求 jsapi_ticket,使用Get请求一下接口即可,返回的 ticket 字段即 jsapi_ticket (需要给运行该接口的机器添加白名单,具体可以看上面的“添加服务器到白名单”小节)
      <https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi>
      
  • 生成签名:得到 jsapi_ticket 之后,就可以生成 JS-SDK 权限验证的签名了。

    • 准备签名需要的参数

      • noncestr(随机字符串)
      • 有效的 jsapi_ticket
      • timestamp(时间戳)
      • url(当前网页的URL,不包含#及其后面部分)
    • 将上面的签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1,如下面的例子

      jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value
      
    • 对string1进行sha1签名,得到 signature

      0f9de62fce790f9a083d5c99e95740ceb90c27ed
      

以上就是生成签名的全过程,建议将这段逻辑写在后端,让后端提供一个生成签名的接口供前端调用,接口接受一个url参数(要分享的网页的URL),返回noncestrjsapi_tickettimestampurlsignature。(需要将运行后端接口的机器添加白名单,具体可以看上面的“添加服务器到白名单”小节)

{
	nonceStr: string; // 随机字符串
	jsapi_ticket: string; // jsapi_ticket
	timestamp: string; // 时间戳
	url: string; // 要分享的网页URL
	signature: string; // 签名
}

获取签名信息参考代码

import crypto from 'crypto-js';
import axios from 'axios'
import random from 'string-random'
const WX_BASE_URL = '<https://api.weixin.qq.com/cgi-bin>'
const APP_ID = 'xxxx'
const APP_SECRET = 'xxxx'

const generatorSha1 = (str) => {
	return crypto.SHA1(str).toString(crypto.enc.Hex)
}

/**
 * 获取Access token
 * 参考:<https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html>
 * 注意运行该方法的电脑ip要加到微信公众号后台的IP白名单中
 */
const getAccessToken = async (appId, appSecret) => {
	if (!appId || !appSecret) return
	const result = await axios.get(`/token?grant_type=client_credential&appid=${appId}&secret=${appSecret}`, { baseURL: WX_BASE_URL });
	console.log('getAccessToken: ', result.data, result.data.access_token)
	return result.data.access_token
}

/**
 * 获签名信息
 * @param {*} url - 要分享的网页链接
 * @returns 
 */
const getSignature = async (url) => {
	if (!url) return
	const accessToken = await getAccessToken(APP_ID, APP_SECRET)
	const getticketResult = await axios.get(`/ticket/getticket?access_token=${accessToken}&type=jsapi`, { baseURL: WX_BASE_URL });
	console.log('jsapi_ticket: ', getticketResult.data, getticketResult.data.ticket)
	const jsapi_ticket = getticketResult.data.ticket
	const nonceStr = random(16) // 'Wm3WZYTPz0wzccnW'
	const timestamp = new Date().getTime()
	const str = `jsapi_ticket=${jsapi_ticket}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${url}`
	const signature = generatorSha1(str)
	const result = {
		nonceStr,
		jsapi_ticket,
		timestamp,
		url,
		signature,
		appId,
	}
	console.log('getSignature: ', result, signature)
	return result
}

微信 JS 接口签名校验工具:可以在这个链接下验证一下签名是否正确

💡 注意:如果使用的是小程序云开发静态网站托管的域名的网页,可以免鉴权直接跳任意合法合规小程序,调用 wx.config 时 appId 需填入非个人主体的已认证小程序,不需计算签名,timestamp、nonceStr、signature 填入非空任意值即可。

3. 通过config接口注入权限验证配置(前端页面调用)

经过上面的生成签名步骤(实际开发中让后端提供一个生成签名的接口,但这里为了调试方面都使用Postman手动请求得到必要的参数)后,我们有了 noncestrjsapi_tickettimestamp,使用这些参数就可以注入配置信息了。

// 参考:<https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html>
import wx from 'weixin-js-sdk'

/**
 * 通过config接口注入权限验证配置
 * 请在前端页面调用
 * @param {Object} params
 */
const wxConfig = async (params) => {
	const { appId, timestamp, nonceStr, signature, jsApiList, onReady, onError } = params
	wx.config({
		debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
		appId, // 必填,公众号的唯一标识
		timestamp, // 必填,生成签名的时间戳
		nonceStr, // 必填,生成签名的随机串
		signature,// 必填,签名
		jsApiList: jsApiList // 必填,需要使用的JS接口列表,具体可以查看JS接口列表:<https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#63>
	});
	// 通过ready接口处理成功验证
	wx.ready(function () {
		// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
		console.log('wx ready')
		onReady && onReady()
	});

	// 通过error接口处理失败验证
	wx.error(function (res) {
		// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
		console.error('wx error', res)
		throw Error(res)
	});
}

将debug 设置为 true 时,每个 wx api 被调用都会弹出一个弹框(如下图),errMsg 为 config:ok 表示调用成功。上线时记得把 debug 设置为 false

image.png

4. 调用分享朋友和分享朋友圈配置api

确保传给 api 的 link 跟 获取签名时使用的 url 完全一致,并且该 url 所在的域名已添加到”公众号后台”的“JS接口安全域名”中,否则调用 api 会失败(报错:”fail link must be in js secure domain list” 或“invalid signature”)

export const shareApp = (params) =>
{
	const { title, desc, link, imgUrl } = params
	// 自定义“分享给朋友”及“分享到QQ”按钮的分享内容
	wx.updateAppMessageShareData({
		title, // 分享标题
		desc, // 分享描述
		link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
		imgUrl, // 分享图标
		success: function ()
		{
			// 设置成功
			console.log('分享给朋友配置成功')
		}
	})

	// 自定义“分享给朋友”及“分享到QQ”按钮的分享内容
	wx.updateTimelineShareData({
		title, // 分享标题
		link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
		imgUrl, // 分享图标
		success: function ()
		{
			// 设置成功
			console.log('分享朋友圈配置成功')
		}
	})

	// 获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口
	wx.onMenuShareWeibo({
	  title, // 分享标题
	  desc, // 分享描述
	  link, // 分享链接
	  imgUrl, // 分享图标
	  success: function () {
		  // 用户确认分享后执行的回调函数
			console.log('分享到腾讯微博成功')
	  },
	  cancel: function () {
		  // 用户取消分享后执行的回调函数
			console.log('取消分享到腾讯微博')
	  }
	});
}

最终代码

调用 wxConfig 时注意要把使用到的接口赋值给 jsApiList,否则会调用失败。

// 参考:<https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html>
import wx from 'weixin-js-sdk'

/**
 * 通过config接口注入权限验证配置
 * 请在前端页面调用
 * @param {Object} params
 */
const wxConfig = async (params) => {
	const { appId, timestamp, nonceStr, signature, jsApiList, onReady, onError } = params
	wx.config({
		debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
		appId, // 必填,公众号的唯一标识
		timestamp, // 必填,生成签名的时间戳
		nonceStr, // 必填,生成签名的随机串
		signature,// 必填,签名
		jsApiList: jsApiList // 必填,需要使用的JS接口列表,具体可以查看JS接口列表:<https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#63>
	});
	// 通过ready接口处理成功验证
	wx.ready(function () {
		// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
		console.log('wx ready')
		onReady && onReady()
	});

	// 通过error接口处理失败验证
	wx.error(function (error) {
		// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
		console.error('wx error', error)
		onError && onError(error)
	});
}

/**
 * 微信Api初始化
 * 请在需要分享的前端页面调用
 * @param {Object} url -需要分享的前端页面
 */
export const wxShareInit = async (url) => {
	const data = await getSignature(url) // 后端提供的获取签名api,具体实现可以看上面的”获取签名信息参考代码”小节
	const { appId, timestamp, nonceStr, signature } = data
	wxConfig({
		appId,
		timestamp,
		nonceStr,
		signature,
		jsApiList: [
			// 分享需要用到以下几个接口
			'updateAppMessageShareData', // 自定义“分享给朋友”及“分享到QQ”按钮的分享内容
			'updateTimelineShareData', // 自定义“分享给朋友”及“分享到QQ”按钮的分享内容
			'updateTimelineShareData', // 获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口
		],
		onReady: () => {
			console.log('初始化成功')
			shareApp({
				title: '我的自定义标题',
				desc: '我的自定义描述',
				link: url,
				imgUrl: '缩略图url',
			}) // 分享配置
		},
		onError: (error) => {
			console.log('初始化失败', error)
		}
	})
}

在需要分享的页面调用 wxShareInit 方法。

try {
	const url = window.location.href.split('#')[0]
	wxShareInit(url)
} catch (error) {
	console.error(error)
}

验证效果

将要分享的页面链接生成一个二维码,然后微信扫码打开链接,然后点击微信右上角图标进行分享(注意:要确保点击该分享按钮前wxShareInit已经执行过了,代码中建议一进入页面就调用wxShareInit),可以发现 标题、描述和缩略图都配置成我们想要的效果啦!

image.png

遇到问题

遇到问题可以先去 JS_SDK说明文档-常见错误及解决方法 看看有没有相同的问题。开发过程中的大部分报错都可以在这里面找到。

以上就是自定义微信分享链接展示的所有内容啦。