公众号网页开发
网页授权
回调域名设置:到公众平台官网中的“开发 – 接口权限 – 网页服务 – 网页帐号 – 网页授权获取用户基本信息”的配置选项中,是填写全域名,不能是泛域名。
特殊场景下的静默授权
- 上面已经提到,对于以snsapi_base为scope的网页授权,就静默授权的,用户无感知;
- 对于已关注公众号的用户,如果用户从公众号的会话或者自定义菜单进入本公众号的网页授权页,即使是scope为snsapi_userinfo,也是静默授权,用户无感知。
网页授权流程分为四步:
1. 引导用户进入授权页面同意授权,获取code
授权后 重定向回来 redirect_uri/?code=CODE&state=STATE (redirect_uri 可以是后端接口地址,获取到code 后直接发起下一步)
2. 通过code换取网页授权access_token(与基础支持中的access_token不同)( 服务器发起)
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE",
"is_snapshotuser": 1,
"unionid": "UNIONID"
}
3. 如果需要,开发者可以刷新网页授权access_token,避免过期
4. 通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
{
"openid": "OPENID",
"nickname": NICKNAME,
"sex": 1,
"province":"PROVINCE",
"city":"CITY",
"country":"COUNTRY",
"headimgurl":"https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
"privilege":[ "PRIVILEGE1" "PRIVILEGE2" ],
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
js-sdk
js-sdk是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包,通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验
使用步骤
1 绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
2 引入JS文件
在需要调用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)
3 通过config接口注入权限验证配置
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用)
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表
});
4 .通过ready接口处理成功验证,error接口处理失败验证
wx.ready(function(){
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
wx.error(function(res){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
完整示例代码
const init = async () => {
const _unitGetSign = function () {
return new Promise(async (resolve, reject) => {
// 获取签名数据
let data = await api.get(`${config.host}/account/jssdkSignature`, {
url: location.href,
activityCode: activityCode,
}, {
method: 'GET',
contentType: 'application/json'
})
wx.signatureDone = true;
let res = data.value;
wx.config({
debug: false, // 留一个开关来启用调试模式
appId: res.appId,
timestamp: res.timestamp,
nonceStr: res.noncestr,
signature: res.signature,
jsApiList: 'updateAppMessageShareData;updateTimelineShareData;checkJsApi;onMenuShareTimeline;onMenuShareAppMessage;onMenuShareQQ;onMenuShareWeibo'.split(';')
})
wx.ready(function () {
resolve(res)
})
})
}
const initApis = () => {
//需在用户可能点击分享按钮前就先调用
wx.updateAppMessageShareData({
title: '', // 分享标题
desc: '', // 分享描述
link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: '', // 分享图标
success: function () {
// 设置成功
}
})
wx.hideMenuItems({
menuList: ['menuItem:copyUrl'] // 要隐藏的菜单项,只能隐藏“传播类”和“保护类”按钮
});
}
if (!window.wx) {
await utilsDynamicFile(['http://res2.wx.qq.com/open/js/jweixin-1.6.0.js ']);
await _unitGetSign(); // 如果是单页面可以通过 wx.signatureDone 判断是否已授权
initApis(shareConfig)
} else {
await _unitGetSign();
initApis(shareConfig)
}
}
签名获取 (服务器上进行)
1.参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token)https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
2. 用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
3 生成签名(见链接),并返回给前端 ,连同签名用的noncestr和timestamp也返回,必须与wx.config中的nonceStr和timestamp相同。
开放标签
可以实现公众号网页跳转 小程序,App,服务号订阅通知按钮,音频播放
<wx-open-launch-weapp>
<wx-open-launch-app>
<wx-open-subscribe>
<wx-open-audio>
小程序Web-view
webview 指向网页的链接。可打开关联的公众号的文章,其它网页需登录小程序管理后台配置业务域名
web-view 引用sdk 不需要签名授权
const ready = async () => {
console.log(window.__wxjs_environment === 'miniprogram') // true
if(!window.wx){
await utilsDynamicFile(['//res.wx.qq.com/open/js/jweixin-1.3.2.js']);
}
wx.miniProgram.postMessage({ data: {title, imgUrl: imagePath, link, shareCode: isNeedShareCode ? (activityConfig.selfShareCode || xCubeShareCode || '') : ''} });
}
if (!window.WeixinJSBridge || !window.WeixinJSBridge.invoke) {
document.addEventListener('WeixinJSBridgeReady', ready, false)
} else {
ready()
}