uniapp开发h5 调用微信sdk 全网最全指南!!!! 血泪史!!!

news2024/11/29 2:37:29

目录

场景:

技术栈:

遇到的问题先抛出来:

1.通过后端同学获取调用微信sdk所需的签名过程中,遇到的跨域问题

2.使用微信sdk前提必须是微信容器,换句话说就是微信浏览器打开,才能使用微信sdk

3.如何在开发本地环境去测试微信sdk的调用情况

4.在微信容器使用微信sdk报错,config报错:config:invalid signature  

5.报错config:fail,invalid url domain

问题1解决办法:

问题2解决办法:

问题3解决办法:

 问题4解决办法:

问题5解决办法:

 上面就阐述完使用过程中遇到的bug:接下来给大家说下使用微信sdk方法和接口封装

在项目中使用

配置

项目中使用:


场景:

公司需求是在h5调用扫一扫来识别条形码,经调研发现使用微信sdk是最好的方式。

技术栈:

uniapp、微信sdk版本:1.6.0

先贴官方文档(踩的所有坑文档里是一句都不提!!!麻蛋)

遇到的问题先抛出来:

1.通过后端同学获取调用微信sdk所需的签名过程中,遇到的跨域问题
2.使用微信sdk前提必须是微信容器,换句话说就是微信浏览器打开,才能使用微信sdk
3.如何在开发本地环境去测试微信sdk的调用情况
4.在微信容器使用微信sdk报错,config报错:config:invalid signature  
5.报错config:fail,invalid url domain

接下来我们来一一解决:

问题1解决办法:

跨域问题是预料之中的问题,uni给到了一些解决方案,我这里就不赘述了,我所选择的方案就是常规的前端做poxy代理:在manifest.json里面设置

uni.request封装时  url参数设置为/api

 

举个例子大家就明白了:

后端给到的实际接口是 wwwx.baidu.com/test

那么我们uni.request的url参数实际是 /api + /test 字符串拼串,这个就代表上图中封装的uni.request里的config.baseUrl + options.url

然后我们设置poxy代理将/api代理为wwwx.baidu.com,那么实际发出去的请求将会自动拼接为:wwwx.baidu.com/api/test   那么大家发现了不对劲的事情就是我们实际后端给的接口是wwwx.baidu.com/test,多了个/api 那么我们还需最后异步就是配置pathRewrite将我们设置的这个/api在实际发送请求时候去掉。

这个时候我们在代码中只要请求接口路径里面出现了 /api, 代理服务器 (http-proxy-middleware) 就会接管这个接口, 现在我们实际上是请求的代理服务器, 而代理服务器会帮我们请求真正的目标接口

①”/api”就是告知,接口以”/api”开头的接口才会代理,所以写请求接口时要使用“/api/xx/xx”的形式

②pathRewrite:作用是代理后的域名会是target+/api , /api并不是我们想要的,所以需要重新请求路径

问题2解决办法:

在h5运行微信sdk前提这个h5要在微信浏览器内打开,也就是说比如微信公众号的h5,微信小程序嵌套的webview,那么本地开发想测试怎么办,那么答案来了!就是用微信开发者工具

 输入域名访问就好了,本地域名也可以的  比如项目运行后network后的域名就可以的,但是随之而来的一个问题就是,只有配置了js安全域名的网页才可以成功调用微信sdk,本地开发环境没办法通过正常去掉去配置安全域名,因为需要下载一个文件然后放在域名根目录下,这个问题会在问题3中解答。

问题3解决办法:

问题2中抛出来的问题,在此提出解决方案,就是微信提供了一套解决方案就是通过微信公众测试号,来去获取使用微信sdk所需的签名以及安全域名配置。此方案是从掘金的一位老哥文章里发现的。

微信测试号申请地址,只需要微信扫码进入就好啦

进入页面后是这样的:

 以我的项目需求为例:调用扫一扫接口

那么只需要两步,

第一步通过页面里面给的测试appid和appsecret,去生成wx.config所需的签名信息

第二步:配置安全域名(作用是,只有配置安全域名的网页才可以成功调用微信sdk)

我们分别详细解释这两步的操作流程:

第一步:通过文章一开始给的微信sdk使用文档里查

文档中获取到我们需要通过appid和秘钥生成 access_token,然后通过access_token去生成jsapi_ticket,然后用jsapi_ticket去换取签名

获取access_token的文档

文档中有个网页测试接口工具点开

 输入刚才的appid和秘钥,这里有个坑就是文档中对于参数grant_type的描述非常奇葩,其实就是个client_credential字符串,我以为是别的什么特殊变量的代称,社区里也有好多关于这个的提问,只能说微信文档垃圾。还有个奇葩的地方就是文档上写这个接口是get请求,但是下面调用的那个页面显示方法是post,真是无语!!!!

经过各种踩坑终于拿到了access_token,之后我们需要用这个access_token来获取jsapi_ticket

接下来这个是没有文档的,文档只给到了一个接口,

https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card接下来使用apipost去调用这个接口去获取最后的jsapi_ticket

最后顺利的拿到了jsapi_ticket 也就是图中的ticket字段 ,获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。

因为我们是测试,就不用上面那么繁琐,所以我们直接使用微信提供的工具来生成:工具地址

这里需要注意的是 

  1. 签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。

  2. 签名用的url必须是调用JS接口页面的完整URL。(这个文档里有详细写:当前网页的URL,不包含#及其后面部分)在sdk使用文档里的附录5-常见错误及解决方法里面有提到url相关内容

  3. 出于安全考虑,开发者必须在服务器端实现签名的逻辑。

我们获取完签名完以后,接下来第二步在测试号管理的那个页面去配置js安全域名这里有个小坑就是配置时候不包含http(s)://,比如图中我的本地访问h5域名是http://100.100.20.174:8080/#/pages/bloodWrite/bindDevice/index

然后这里配置只需要 100.100.20.174:8080

这里需要讲一下,就是上面关于签名的获取,正常是需要后端去获取,我们调用后端的接口,传递当前访问微信sdk接口的网页域名作为参数(这个url必须满足下面条件) 后端会返回给你签名的

 

 那么我们js安全域名配置好,就拥有了成功访问微信sdk的资质,接下来是调用,调用微信sdk之前需要调用wx.config,其中填入的参数之一就是我们刚获取的签名

这里需要注意:签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。

 接下来在微信开发者工具里面打开本地ip域名访问h5  在里面去调用就会发现我们成功了

 问题4解决办法:

报这个错其实就是我一开始使用后端获取的签名(这里获取签名用的appid和秘钥都是公司的公众号(服务号)信息),这就意味着,我必须把项目部署到线上,并且部署线上的那个域名配置js安全域名后才可以成功访问微信sdk,不然就会报错

问题5解决办法:

这个报错其实就是上面提及到的我在用测试号的信息获取签名,来进行本地测试sdk时候,过程中将本地ip配置成js安全域名时候带上了http(s)://,导致报错


 上面就阐述完使用过程中遇到的bug:接下来给大家说下使用微信sdk方法和接口封装

npm方式使用下方指令进行安装

npm install jweixin-module --save  

在项目中使用

为了方便使用,我单独出一个微信相关的 js 文件,进行相关的初始化等操作。
wechat.js

import jWeixin from 'weixin-js-sdk'
import { wxSDKAuthority } from '@/api/login/login.js'


export default {
	/* 判断是否在微信中 */
	isWechat: function() {
		var ua = window.navigator.userAgent.toLowerCase();
		console.log(ua);
		if (ua.match(/micromessenger/i) == 'micromessenger') {
			//console.log('是微信客户端')  
			return true;
		} else {
			//console.log('不是微信客户端')  
			//以下是我项目中所需要的操作其他,可以自定义
			uni.showModal({
				title: '提示',
				content: '请在微信浏览器中打开',
				showCancel: false,
				confirmColor: '#00875a',
				success: function(res) {
					if (res.confirm) {
						// console.log('用户点击确定');
					} else if (res.cancel) {
						// console.log('用户点击取消');
					}
				}
			});
			return false;
		}
	},
	/* 获取sdk初始化配置 */
	initJssdk: async function(callback) {
		//获取当前url然后传递给后台获取授权和签名信息  
		var url = encodeURIComponent(window.location.href.split('#')[0]); //当前网页的URL,不包含#及其后面部分
		console.log(window.location.href.split('#')[0]);
		let res = await wxSDKAuthority({ url }) //这里调用的是后端的接口,后端去获取签名以及config里面所需的信息
		//返回需要的参数appId,timestamp,noncestr,signature等
		//注入config权限配置  
		const { appId, timestamp, nonceStr, signature } = res.content;
		jWeixin.config({
			debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
			// beta: true, // 文档没有这个参数,这个参数需设为true,才能调用那些微信还没有正式开放的新接口比如wx.invoke
			appId: appId, // 必填,公众号的唯一标识
			timestamp: timestamp, // 必填,生成签名的时间戳
			nonceStr: nonceStr, // 必填,生成签名的随机串
			signature: signature, // 必填,签名
			jsApiList: [ // 必填,需要使用的JS接口列表
				// 'checkJsApi', //判断当前客户端版本是否支持指定JS接口  
				// 'updateAppMessageShareData', //分享朋友
				// 'updateTimelineShareData', //分享朋友圈  
				// 'getLocation', //获取位置  
				// 'openLocation', //打开位置  
				'scanQRCode', //扫一扫接口  
				// 'chooseWXPay', //微信支付  
				// 'chooseImage', //拍照或从手机相册中选图接口  
				// 'previewImage', //预览图片接口  
				// 'uploadImage' //上传图片  
			]
		});
		// 本地环境测试使用,里面信息是测试号的appid和签名
		// jWeixin.config({
		// 	debug: true,
		// 	appId: 'wx451eff21c6c0d938',
		// 	timestamp: 1659065946,
		// 	nonceStr: 'dzklsf',
		// 	signature: 'd2ada1c92409e14c9e720ed58056dcd3800ab0a7',
		// 	jsApiList: ['scanQRCode']
		// })
		// 本地环境测试结束

		if (callback) {
			callback(res.content);
		}
	},
	//微信扫码
	scanQRCode: function(callback) {
		if (!this.isWechat()) {
			//console.log('不是微信客户端')  
			return;
		}
		this.initJssdk(function(res) {
			jWeixin.ready(function() {
				jWeixin.scanQRCode({
					needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
					scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
					success: function(res) {
						// console.log(res);  
						callback(res);
					},
					fail: function(res) {
						callback(res)
					},
				});
			});
		});
	},
	//在需要定位页面调用  
	getlocation: function(callback) {
		if (!this.isWechat()) {
			//console.log('不是微信客户端')  
			return;
		}
		this.initJssdk(function(res) {
			jWeixin.ready(function() {
				jWeixin.getLocation({
					type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'  
					success: function(res) {
						// console.log(res);  
						callback(res)
					},
					fail: function(res) {
						console.log(res)
					},
				});
			});
		});
	},
	//打开位置  
	openlocation: function(data, callback) {
		if (!this.isWechat()) {
			//console.log('不是微信客户端')  
			return;
		}
		this.initJssdk(function(res) {
			jWeixin.ready(function() {
				jWeixin.openLocation({ //根据传入的坐标打开地图  
					latitude: data.latitude,
					longitude: data.longitude
				});
			});
		});
	},
	//选择图片  
	chooseImage: function(callback) {
		if (!this.isWechat()) {
			//console.log('不是微信客户端')  
			return;
		}
		//console.log(data);  
		this.initJssdk(function(res) {
			jWeixin.ready(function() {
				jWeixin.chooseImage({
					count: 1,
					sizeType: ['compressed'],
					sourceType: ['album'],
					success: function(rs) {
						callback(rs)
					}
				})
			});
		});
	},
	//微信支付  
	wxpay: function(data, callback) {
		if (!this.isWechat()) {
			//console.log('不是微信客户端')
			return;
		}
		this.initJssdk(function(res) {
			jWeixin.ready(function() {
				jWeixin.chooseWXPay({
					timestamp: data.timestamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符  
					nonceStr: data.nonceStr, // 支付签名随机串,不长于 32 位  
					package: data.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)  
					signType: data.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'  
					paySign: data.paysign, // 支付签名  
					success: function(res) {
						// console.log(res);  
						callback(res)
					},
					fail: function(res) {
						callback(res)
					},
				});
			});
		});
	},

	//自定义分享  这里我统一调用了分享到朋友和朋友圈,可以自行定义
	share: function(callback) {
		if (!this.isWechat()) {
			//console.log('不是微信客户端')  
			return;
		}
		this.initJssdk(function(res) {
			jWeixin.ready(function() {

				//我的分享配置由后台返回,可以自定义
				http.get({
					url: 'getShareInfo'
				}).then(res => {
					const { shareInfo } = res.data;
					jWeixin.updateAppMessageShareData({ //分享给朋友
						title: shareInfo.title,
						desc: shareInfo.description,
						imgUrl: shareInfo.image,
						link: shareInfo.link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
						success: function() {
							// 用户确认分享后执行的回调函数
							callback(res);
						}
					});
					jWeixin.updateTimelineShareData({ //分享到朋友圈
						title: shareInfo.title,
						desc: shareInfo.description,
						imgUrl: shareInfo.image,
						link: shareInfo.link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
						success: function() {
							// 用户确认分享后执行的回调函数
							callback(res);
						}
					});
				});
			});
		});
	}
}

配置

我是挂载到全局中使用的
在main.js中引入

import wechat from '@/common/wechat '
Vue.prototype.$wx = wechat

项目中使用:

<template>
	<button @click="scanQRCode">扫码</button>
</template>
<script>
	export default {
		data() {},
		methods:{
			scanQRCode(){
				this.$wx.scanQRCode((res) => {
					if (res.errMsg == "scanQRCode:ok") {
						this.inputVal = res.resultStr
					}
				})
           }
		}
	}
</script>
<style>
</style>

至此全文结束,能读到这里,兄弟你也是牛,但是我这一篇虽然像老太太的裹脚布,但是可以帮你避免踩很多坑! 有问题评论区找我,知无不言! 如果对你真的有帮助,希望不要吝啬,请一键三连!!!接下来要继续我的踩坑之旅了! gaoci

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1028267.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

方案:浅析利用AI智能识别与视频监控技术打造智慧水产养殖监管系统

一、方案背景 针对目前水产养殖集约、高产、高效、生态、安全的发展需求&#xff0c;基于智能传感、智慧物联网、人工智能、视频监控等技术打造智慧水产系统&#xff0c;成为当前行业的发展趋势。传统的人工观察水产养殖方式较为单一&#xff0c;难以及时发现人员非法入侵、偷…

Windows系统如何部署Wing FTP Server与公网远程访问【内网穿透】

Wing FTP Server安装配置结合内网穿透实现公网访问本地站点 文章目录 Wing FTP Server安装配置结合内网穿透实现公网访问本地站点前言1.Wing FTP Server下载安装2.Wing FTP Server配置部署3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3…

ChatGLM 实现一个BERT

前言 本文包含大量源码和讲解,通过段落和横线分割了各个模块,同时网站配备了侧边栏,帮助大家在各个小节中快速跳转,希望大家阅读完能对BERT有深刻的了解。同时建议通过pycharm、vscode等工具对bert源码进行单步调试,调试到对应的模块再对比看本章节的讲解。 涉及到的jupyt…

【多目标跟踪】 TrackFormer 耗时三天 单句翻译!!!

【多目标跟踪】 TrackFormer 耗时三天 单句翻译&#xff01;&#xff01;&#xff01; TrackFormer: Multi-Object Tracking with Transformers Abstract The challenging task of multi-object tracking (MOT) re-quires simultaneous reasoning about track initiali…

纽禄美卡Neuromeka亮相美国FABTECH,展示用于焊接的3D视觉协作机器人

原创 | 文 BFT机器人 纽禄美卡Neuromeka公司在由美国精密成型协会、美国焊接协会、化工涂料协会等5大协会举办的美国金属加工及焊接展览会FABTECH上精彩亮相。这家总部位于韩国首尔的公司成立于2013年&#xff0c;是机器人解决方案领域的领先供应商&#xff0c;致力于提高各种…

通过 chatgpt 协助完成网站数据破解

Chatgpt 的出现极大地提升了程序员的工作效率&#xff0c;常见的使用场景包括代码自动生成、代码静态检查等&#xff0c;那么 chatgpt 能否用于某些网站的数据破解工作呢&#xff1f; 问题 某天线上服务开始报警&#xff0c;原来是某个视频网站无法获取到其 cdn 地址导致的下…

【AD】【规则设置】设置四层板

设置四层板 一般 4层板&#xff0c;都会把 地 和 VCC放在内层。1、使用快捷键D-K 进入层叠管理器&#xff0c;添加负片层添加完后&#xff0c;修改层名&#xff0c;方便辨识修改格式&#xff1a;属性层号 2、进入相应layer 设置网络设置GND层设置VCC层特点&#xff1a;在层内可…

【HackTheBox Topology】打靶记录

一、信息收集 1、nmap 扫描发现22 80 端口 2、访问80端口 找到两个域名 topology.htb latex.topology.htb 3、子域扫描发现如下两个域名 dev.topology.htb stats.topology.htb C:\root> gobuster vhost -u http://topology.htb --append-domain -w /usr/share/seclists…

【Android Framework系列】第15章 Fragment+ViewPager与Viewpager2相关原理

1 前言 上一章节【Android Framework系列】第14章 Fragment核心原理(AndroidX版本&#xff09;我们学习了Fragment的核心原理&#xff0c;本章节学习常用的FragmentViewPager以及FragmentViewPager2的相关使用和一些基本的源码分析。 2 FragmentViewPager 我们常用的两个Page…

【基本数据结构 四】线性数据结构:队列

学习了栈后,再来看看第四种线性表结构,也就是队列,队列和栈一样也是一种受限的线性表结构,和栈后进先出的操作方式不同的是,队列是FIFO的结构,也就是先进先出的操作方式。 队列的定义 队列这个概念非常好理解。可以把它想象成排队买票,先来的先买,后来的人只能站末尾…

iTOP-RK3568开发板Linux 修改kernel logo

本文档配套资料在网盘资料“iTOP-3568 开发板\02_【iTOP-RK3568 开发板】开发资料\10_Linux 系统开发配套资料\05_Linux 修改内核 logo 配套资料”路径下。 5.3.1 准备 logo 系统默认内核 logo&#xff0c;如下图所示&#xff1a; 如 果 想 要 替 换 这 个 logo, 首 先 要 制…

SAP服务器文件管理

SAP服务器文件管理 文件说明&#xff1a;对于SAP服务器的文件管理&#xff0c;系统给出3个事物码&#xff0c;分别是显示目录的AL11&#xff0c;下载文件的 CG3Y和上传文件的CG3Z。 AL11显示目录:以查找系统参数文件为例&#xff0c;在前台执行事物码AL11进入&#xff0c;如图…

【面试经典150 | 数组】多数元素

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;哈希表方法二&#xff1a;排序方法三&#xff1a;摩尔投票法 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主…

HelpLook全新升级!定制AI问答机器人,企业内容中心焕新

一直以来&#xff0c;企业都在努力解决内外部“企业知识管理”问题&#xff1a;从纸质手册发放&#xff0c;转线上电子文档传阅(pdf/ppt/word等)&#xff0c;再到整理客户常见问题(FAQ)和内部知识库(wiki)&#xff0c;但始终没有找到一套完整方案将“企业知识”很好地集中管理及…

不得不爱的AI艺术写真头像二维码生成小程序开发

最近什么最火&#xff1f;AI最火&#xff01; AI里什么最火&#xff1f;艺术写真生成和二维码美化最火。 一款小程序集合了高还原度的AI写真艺术照和二维码美化&#xff0c;你们说香还是不香&#xff1f; 并且加入了输入心愿就能生成独一无二的个性头像功能&#xff0c;直接…

zabbix自定义监控内容案例

一、自定义监控内容 案列&#xff1a;自定义监控客户端服务器登录的人数需求&#xff1a;限制登录人数不超过 3 个&#xff0c;超过 3 个就发出报警信息 1、在客户端创建自定义key 明确需要执行的linux命令 创建zabbix监控项配置文件&#xff0c;用于自定义Key #在zabbix的…

vmware创建的虚拟机无法连接外网

在我本机中使用vmware创建虚拟机后&#xff0c;安装 docker 时使用wget 命令下载docker的安装文件 报错找不到资源&#xff0c;然后通过ping www.baidu.com 发现也ping不通&#xff0c;经过一番折腾可以访问外网了&#xff0c;将步骤记录下来&#xff1b; 1、设置虚拟机的网络…

【Python小项目之Tkinter应用】随机点名/抽奖工具大优化:新增查看历史记录窗口!语音播报功能!修复预览文件按钮等之前版本的bug!

文章目录 前言一、实现思路二、关键代码查看历史记录按钮语音播报按钮三、完整代码总结前言 老生常谈,先看效果:(订阅专栏可获取完整代码) 初始状态下,我们为除了【设置】外的按钮添加弹窗,提示用户在使用工具之前要先【设置】。在设置界面,我们主要修改了【预览文件】…

golang 自动生成文件头

安装koroFileHeader控件 打开首选项&#xff0c;进入设置&#xff0c;配置文件头信息"fileheader.customMade": {"Author": "lmy","Date": "Do not edit", // 文件创建时间(不变)// 文件最后编辑者"LastEditors"…

研究生选控制嵌入式还是机器视觉好?

研究生选控制嵌入式还是机器视觉好&#xff1f; 我是嵌入式/硬件方向转的算法&#xff0c;现在是公司的算法负责人&#xff0c;如果再让我选一次&#xff0c;我是不会再选嵌入式方 向&#xff0c;嵌入式如果只做技术是没前途的。 你要是有一定自学能力&#xff0c;能自己在学校…