uniapp develops h5 and calls WeChat sdk. The most complete guide on the entire network! ! ! ! A history of blood and tears! ! !

Table of contents

Scenes:

Technology stack:

Let’s throw out the problems encountered first:

1. Cross-domain issues encountered during the process of obtaining the signature required to call WeChat SDK through back-end classmates

2. The prerequisite for using WeChat SDK is a WeChat container. In other words, the WeChat browser must be opened before WeChat SDK can be used.

3. How to test the calling status of WeChat SDK in the local development environment

4. When using WeChat sdk in the WeChat container, an error is reported, and config reports an error: config: invalid signature  

5. Error config:fail,invalid url domain

Solution to problem 1:

Solution to problem 2:

Solution to problem 3:

 Solution to problem 4:

Solution to problem 5:

 The above has explained the bugs encountered during use: Next, I will tell you about the use of WeChat SDK methods and interface encapsulation

Use in projects

Configuration

Used in the project:


Scenes:

The company's requirement is to call scan on h5 to identify barcodes. After research, it was found that using WeChat SDK is the best way.

Technology stack:

uniapp, WeChat sdk version: 1.6.0

Post the official documents first (not a single word is mentioned in all the cheating documents that I have followed!!! Damn)

Let’s throw out the problems encountered first:

1. Cross-domain issues encountered during the process of obtaining the signature required to call WeChat SDK through back-end classmates
2. The prerequisite for using WeChat SDK is a WeChat container. In other words, the WeChat browser must be opened before WeChat SDK can be used.
3. How to test the calling status of WeChat SDK in the local development environment
4. When using WeChat sdk in the WeChat container, an error is reported, and config reports an error: config: invalid signature  
5. Error config:fail,invalid url domain

Next we will solve them one by one:

Solution to problem 1:

Cross-domain problems are expected. uni has provided some solutions , which I won’t go into details here. The solution I chose is to use a conventional front-end proxy proxy: set it in manifest.json

When encapsulating uni.request, the url parameter is set to /api

 

Everyone will understand with an example:

The actual interface given by the backend is wwwx.baidu.com/test

Then the url parameter of our uni.request is actually /api + /test string concatenation, which represents the config.baseUrl + options.url in the uni.request encapsulated in the picture above.

Then we set up the proxy proxy to proxy /api to wwwx.baidu.com, then the actual request sent will be automatically spliced ​​into: wwwx.baidu.com/api/test Then what everyone found wrong was that our actual backend The interface is wwwx.baidu.com/test. If there is an additional /api, then we still need to configure pathRewrite asynchronously to remove the /api we set when actually sending the request.

At this time, as long as /api appears in the request interface path in the code, the proxy server (http-proxy-middleware) will take over this interface. Now we are actually the proxy server for the request, and the proxy server will help us request the real target interface

①"/api" is to inform that only the interface starting with "/api" will be proxied, so when writing the request interface, use the form of "/api/xx/xx"

②pathRewrite: The function is that the domain name after proxy will be target+/api. /api is not what we want, so we need to request the path again.

Solution to problem 2:

The prerequisite for running WeChat SDK in h5 is that the h5 must be opened in the WeChat browser, that is to say, for example, the h5 of the WeChat official account and the nested webview of the WeChat applet. So what should you do if you want to test local development? Here is the answer! Just use WeChat developer tools

 Just enter the domain name to access. Local domain names can also be used. For example, after the project is run, the domain name after network can be used. However, a problem that comes with it is that only web pages configured with js secure domain names can successfully call WeChat SDK. Local The development environment cannot configure a secure domain name by removing it normally, because a file needs to be downloaded and placed in the root directory of the domain name. This question will be answered in Question 3.

Solution to problem 3:

The solution to the problem raised in question 2 is that WeChat provides a set of solutions that use the WeChat public test account to obtain the signatures and secure domain name configuration required to use the WeChat SDK. This plan was discovered from an article by an old man from the Nuggets .

To apply for the WeChat test account address , you only need to scan the WeChat code to enter.

After entering the page, it looks like this:

 Take my project requirements as an example: call the scan interface

Then it only takes two steps,

The first step is to generate the signature information required by wx.config through the test appid and appsecret given in the page.

Step 2: Configure a secure domain name (the effect is that only web pages configured with a secure domain name can successfully call WeChat SDK)

We explain the operation process of these two steps in detail:

Step 1: Check the WeChat sdk usage documentation given at the beginning of the article

According to the document, we need to generate access_token through appid and secret key, then use access_token to generate jsapi_ticket, and then use jsapi_ticket to exchange for signature

Get the document of access_token

There is a web page testing interface tool in the document, click on it

 Enter the appid and secret key just now. There is a pitfall here. The description of the parameter grant_type in the document is very strange. In fact, it is just a client_credential string. I thought it was the name of some other special variable. There are many questions about this in the community. I can only say that WeChat documents are garbage. Another strange thing is that the document says that this interface is a get request, but the page display method called below is post. I am really speechless! ! ! !

After all kinds of pitfalls, we finally got the access_token. Then we need to use this access_token to get jsapi_ticket.

There is no documentation for this next one. The documentation only provides an interface.

https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card Next use apipost to call this interface to get the final jsapi_ticket

Finally, we successfully obtained jsapi_ticket, which is the ticket field in the figure. After obtaining jsapi_ticket, we can generate a signature for JS-SDK permission verification.

Because we are testing, we don’t need to be as cumbersome as above, so we directly use the tools provided by WeChat to generate: tool address

What needs to be noted here is that 

  1. The noncestr and timestamp used for signature must be the same as the nonceStr and timestamp in wx.config.

  2. The URL used for signing must be the complete URL of the page calling the JS interface. (This document contains details: the URL of the current web page, excluding # and its following parts) URL-related content is mentioned in Appendix 5 - Common Errors and Solutions in the SDK usage document.

  3. For security reasons, developers must implement signature logic on the server side.

After we obtain the signature, the next step is to configure the js secure domain name on the page managed by the test account. There is a small pitfall in that the configuration does not include http(s)://, such as my local access h5 in the picture. The domain name is http://100.100.20.174:8080/#/pages/bloodWrite/bindDevice/index

Then the configuration here only needs 100.100.20.174:8080

What needs to be mentioned here is the acquisition of the signature above. Normally, the backend is required to obtain it. We call the backend interface and pass the domain name of the web page currently accessing the WeChat SDK interface as a parameter (this URL must meet the following conditions). The backend will return to your signature

 

 Then after our js secure domain name is configured, we have the qualifications to successfully access WeChat sdk. The next step is to call. Before calling WeChat sdk, we need to call wx.config. One of the parameters filled in is the signature we just obtained.

Note here: the noncestr and timestamp used for signature must be the same as the nonceStr and timestamp in wx.config.

 Next, open the local IP domain name in the WeChat developer tool to access h5. When calling it, you will find that we have succeeded.

 Solution to problem 4:

The error reported is actually the signature I obtained using the backend at the beginning (the appid and secret key used to obtain the signature here are the company's official account (service account) information), which means that I must deploy the project online , and deploy the online domain name and configure the js secure domain name before you can successfully access WeChat sdk, otherwise an error will be reported.

Solution to problem 5:

This error is actually the above-mentioned error when I used the test account information to obtain a signature for local testing of the SDK. During the process, I configured the local IP as a js secure domain name and added http(s)://, which resulted in an error.


 The above has explained the bugs encountered during use: Next, I will tell you about the use of WeChat SDK methods and interface encapsulation

npm method use the following command to install

npm install jweixin-module --save  

Use in projects

For ease of use, I created a separate js file related to WeChat to perform related initialization and other operations.
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);
						}
					});
				});
			});
		});
	}
}

Configuration

I mounted it globally
and introduced it in main.js.

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

Used in the project:

<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>

This is the end of the full article. If you can read this far, brother, you are also a genius, but although my article is like an old lady’s foot wrap, it can help you avoid many pitfalls! If you have any questions, ask me in the comment section and let me know! If it's really helpful to you, I hope you won't be stingy, please click three times! ! ! Next, I will continue my pit-trapping journey! gaoci

Guess you like

Origin blog.csdn.net/m0_57033755/article/details/133128026