评论

企微环境下wx.config踩坑指南

企微环境下wx.config签名失败,jsApiList为空数组等常见问题排查

近期项目中遇到要企微h5中使用微信jssdk中的api

一番折腾各种错误这里总结一下,希望能帮到大家(只针对企微下使用微信jssdk的API的场景)

1.ticket导致签名错误

一般情况下比如自定义分享 定位这些普通接口我们使用wx.config 即可, wx.agentConfig是企微一些专门的接口用的,config和agentConfig这两个api的签名参数ticket获取接口是不同的,这里一定要告知后端仔细看文档。config是用第一个接口获取ticket。 agentConfig是使用下面第二个获取ticket,两者不能错乱,错了会导致真机测试报params_empty之类的错误提示

`https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=${access_token}`

`https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token=${access_token}&type=agent_config&debug=1`


2.url不匹配

除了ticket用错外,url错误也是常见的,vue项目中hash模式下基本可以直接写死,因为#号开始后面的部分微信不验证,如果你传了就不匹配。你页面的访问地址一定要和你传给后端用于计算签名的url参数相同(注意vue项目#号的问题),另外你的访问域名一定要在企微自建应用的js安全域名中设置,尽量真机真实域名企微下测试,本地要测试的话改host 本地ip映射到域名上(容易坑,不推荐)。真机下能更直观的发现问题,开发工具调试是微信环境,企微的很多api调不到。

还有一个坑是如果接口是get 你传给后端的url默认会url编码,也会造成url不一致的错误,让后端decode解码url再用或者接口改为post可以避免此问题。

其他错误:提示企业id不匹配就是签名使用的企业id跟当前访问项目的地址所使用的企业不匹配,(多企业的情况下注意切换到对应企业下再测试),提示params_empty的就是ticket用错了,authur就是url不匹配,(仔细看错误里提示的url跟你传给后端的url有什么差别)。

工具里测试config提示config ok然后Apilist为空或者几个没用的接口的话这种其实是config调用失败的,在企微下真机访问就能看到真实错误。可以将全部api列表都添加进去来测试,我测试的时候是有7个api即使config有问题(真机下)在开发工具里也能获取到,正常应该有二十几个,所以开发工具提示不准确,只能作为参考。


企微详细文档地址: https://developer.work.weixin.qq.com/document/14932

企微错误码查询工具:https://open.work.weixin.qq.com/devtool/query

附上我这边的前后端代码

后端代码 以下代码为uni云开发的控制器部分只能做逻辑和流程参考 不能直接使用

const Controller = require("uni-cloud-router").Controller;
var sha1 = require('sha1');
module.exports = class QywxController extends Controller {
  async jssdk() {
    //获取access_token 以及ticket  此处仅为演示 故不做缓存 实际应用中请留意。  下面三参数换成你自己的
	const secret = "xxxxxxxxxxxxxxxxx" //应用的secret
	const corpid = "xxxxxxxx" //企业id
	const agentId = "1000002" //应用ID
	const res = await uniCloud.httpclient.request(`https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${corpid}&corpsecret=${secret}`, {
	    method: 'GET',
	    data: {
	    },
	    contentType: 'json', 
	    dataType: 'json' 
	  })
	console.log(res.data.access_token)


	let access_token = res.data.access_token
	let tokenUrl = `https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=${access_token}`
	// let toeknurl = `https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token=${access_token}&type=agent_config&debug=1`//agentConfig用这个接口
	const res1 = await uniCloud.httpclient.request(tokenUrl, {
	    method: 'GET',
	    data: {
	    },
	    contentType: 'json',
	    dataType: 'json' 
	})
	
	const noncestr = "abcdefgsdf"//随机字符串 ,图方便直接写死了 没影响
	const TIMESTAMP = Date.parse(new Date())/1000
	let {url}  = this.ctx.data;
	url = decodeURIComponent(url)
	// const url = "https://ac.isuoge.com/index.html"
	const signstr = `jsapi_ticket=${res1.data.ticket}&noncestr=${noncestr}×tamp=${TIMESTAMP}&url=${url}`
	var data = {
		"appId":corpid,
		"corpid":corpid,
		"agentid":agentId,
		"timestamp":TIMESTAMP,
		"nonceStr":noncestr,
		"signature":sha1(signstr),
		"access_token":access_token,
		"signstr":signstr,
		"url":url
	}
//access_token,signstr,url,corpid,agentid 都不是必须给前端的 只是为了方便调试核对参数所以返回
	console.log(res1,data)
	return data;
  }


}



前端部分 我这里图方便直接写在index.html上测试的

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
    <title></title>
	<script src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
	<script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script> 
	<script src="//res.wx.qq.com/wwopen/js/jsapi/jweixin-1.0.0.js"></script>
    <!--preload-links-->
    <!--app-context-->
  </head>
  <body>
    <div id="app"><!--app-html--></div>
	<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
	<script>
		$.ajax({url:"https://unicloud-lucky.isuoge.com/api/qywx/jssdk",success:function(res){
			console.log(res)
		    var apilist = [
		    	"onHistoryBack",
		    	"scanQRCode",
		    	"invoke",
		    	"updateAppMessageShareData",
		    	"updateTimelineShareData",
		    	"onMenuShareTimeline",
		    	"onMenuShareAppMessage",
		    	"onMenuShareQQ",
		    	"onMenuShareWeibo",
		    	"onMenuShareQZone",
		    	"startRecord",
		    	"stopRecord",
		    	"onVoiceRecordEnd",
		    	"playVoice",
		    	"pauseVoice",
		    	"stopVoice",
		    	"onVoicePlayEnd",
		    	"uploadVoice",
		    	"downloadVoice",
		    	"chooseImage",
		    	"previewImage",
		    	"uploadImage",
		    	"downloadImage",
		    	"translateVoice",
		    	"getNetworkType",
		    	"openLocation",
		    	"getLocation",
		    	"hideOptionMenu",
		    	"showOptionMenu",
		    	"hideMenuItems",
		    	"showMenuItems",
		    	"hideAllNonBaseMenuItem",
		    	"showAllNonBaseMenuItem",
		    	"closeWindow",
		    	"scanQRCode",
		    	"chooseWXPay",
		    	"openProductSpecificView",
		    	"addCard",
		    	"chooseCard",
		    	"openCard"
		    ] //部分接口config调用失败在工具里也能列出几个,测试为消除影响这里直接把全部接口列出了,实际使用时根据需要添加即可
		    wx.config({
		        beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
		        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
		        ...res.data,
		        jsApiList: apilist, // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
		    	complete:function(ret){
		    		// alert(JSON.stringify(ret))
		    	}
		    });
		    // wx.agentConfig({
		    // 	...res.data,
		    // 	jsApiList: apilist, //必填,传入需要使用的接口名称
		    // 	complete:function(ret){
		    // 		alert(JSON.stringify(ret))
		    // 	},
		    // 	success: function(res) {
		    //         // 回调
		    // 		console.log(res)
		    //     },
		    //     fail: function(res) {
		    //         if(res.errMsg.indexOf('function not exist') > -1){
		    //             alert('版本过低请升级')
		    //         }
		    //     }
		    // });
		}});
		
		
		function h5Share(){
			wx.ready(() => {
			    console.log('初始化js-sdk成功');
			    wx.checkJsApi({
			        jsApiList: ['getLocation'],
			        success(res) {
			            if (res.checkResult.getLocation === false) {
			                const message = '你的微信版本太低,不支持微信JS接口,请升级到最新的微信版本!'
			                reject(message);
			            } else {
			                const message = 'js-sdk检查成功';
			                console.log(message);
			                resolve(message);
			            }
			        },
			        fail(res) {
			            const message = 'checkJsApi fail=' + JSON.stringify(res);
			            console.log(message);
			            reject(message);
			        }
			    });
				
				wx.onMenuShareAppMessage({
				  title: '分享标题修改成功', // 分享标题
				  desc: '分享描述', // 分享描述
				  link: 'https://ac.isuoge.com/admin', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
				  imgUrl: 'https://ac.isuoge.com/static/cat.png', // 分享图标
				  type: 'link', // 分享类型,music、video或link,不填默认为link
				  dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
				  success: function () {
				    // 用户点击了分享后执行的回调函数
				  }
				});
				// wx.updateAppMessageShareData({ 
				//     title: '后台入口', // 分享标题
				//     desc: '测试123', // 分享描述
				//     link: 'https//ac.isuoge.com/admin', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
				//     imgUrl: 'https//ac.isuoge.com/static/cat.png', // 分享图标
				//     success: function (ret) {
				//       // 设置成功
				// 	  console.log(ret)
				//     }
				// })
				
			});
			
			
		}
		
		h5Share()
	</script>
  </body>
</html>

亲测可行 正常情况开发工具里能列出大概27条可用API 企微真机下测试能修改分享标题等

微信开发工具调试信息

真机测试

分享测试


最后一次编辑于  2022-04-13  
点赞 2
收藏
评论
登录 后发表内容