小元
博客
详情文字在这里缓缓展开
静候你翻开这一页

小程序获取手机号前端解析篇(2)

在上一篇文章“小程序获取手机号”中讲述了如何获取code、小程序Id、小程序密钥以及已经后端的解析方案,在本文中将详解在前端如何解析code获取手机号

小程序获取手机号前端解析方案


   前言:

       书接上文,在上一篇文章中拆解了如何获得CodeAppIDAppSecret、在本篇文章中将说明如何不经后端在前端进行解析获取用户手机号。

       ? 前文链接


   注意:

       总的来说在前端解析code的弊端大于后端,主要体现在以下几点。

           1)无法共享ACCESS_TOKEN,由于前端缓存是存储在本地的无法像后端一样存储到服务器上,这就导致每个用户在登录时都会重新获取一次ACCESS_TOKEN,如果用户量体大就会触发超频限制,导致当日无法在获取或解析。

           2)不安全,在前端进行解析,就会用到小程序密钥等,会明文存放在业务代码中。


   实现过程:

       1. 获取code并保存code

           此方法在上一篇文中有具体讲解此处不在详解,代码演示:

<template>
	<view>
		<button open-type="getPhoneNumber" @getphonenumber="decryptPhoneNumber">登录</button>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				code: null,
			}
		},
		methods: {
			// 获取code
			decryptPhoneNumber(e) {
				// 根据业务需求调整
				let errMsg = null;
				if (e.detail.errMsg.includes('fail user deny')) errMsg = "登录失败,您已拒绝获取信息!";
				else if (!e.detail.code) errMsg = "登录失败,获取信息异常!";
				
				if (errMsg) {
					uni.showToast({
						title: errMsg,
						icon: "none"
					});
					
					return;
				}
				
				// 获取Code
				this.code = e.detail.code;
				console.log("code -------->" + this.code);
			}
		}
	}
</script>


           此时点击登录会弹出如下提示:

           1716539462094.png


       2. 获取ACCESS_TOKEN

           本文为了示列在mounted处调用函数进行获取TOKEN,你可以为进一步优化,比如在获取code后在调用防止用户进来后没登录,造成次数占用。

           ? 有关获取令牌的官方说明

           ? TOKEN会在两小时后失效。

           ? 这里为了演示并没有吧token缓存到本地,您可以根据业务需要进行缓存,在缓存时记得存下当前时间,便于超时后重新获取

           代码示列:

// 获取TOKEN
queryAccessToekn() {
	if (this.token) return;
	
	uni.request({
		url: "https://api.weixin.qq.com/cgi-bin/token",
		method: "GET",
		data: {
			grant_type: "client_credential",
			appid: "填入之前获取的AppID",
			secret: "填入之前获取的AppSecret"
		},

		success: (res) => {
			if (!res) return;
			this.token = res.data.access_token;
		}
	})
},


       3. 解析Code获取手机号

           ? Code时效为五分钟

           ? 官网文档说明

           代码示列解析Code:

// 解析Code,为了方便处理不管成功失败都走resolve返回,返回为string类型代表成功
analysisCode () {
	return new Promise((resolve, reject) => {
		uni.request({
			url: `https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=${this.token}`,
			method: "POST",
			data: {
				code: this.code
			},
			success: (res) => {
				if (!res) {
					resolve(false);
					return;
				}
				
				if (res.data.phone_info && res.data.phone_info.phoneNumber) {
					resolve(res.data.phone_info.phoneNumber); // 返回手机号
					return;
				}
				
				resolve(false);
			}
		})
	})
},

           在获取Code处调用:

// 获取Code
this.code = e.detail.code;
console.log("code -------->" + this.code);

// 解析code获取手机号
const res = await this.analysisCode();
console.log("phone ------->" + res);

if (typeof res === "boolean") {
	// 获取失败处理
	return
}

// 获取到手机号之后的逻辑

   

   完整代码:

<template>
	<view>
		<button open-type="getPhoneNumber" @getphonenumber="decryptPhoneNumber">登录</button>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				code: null,
				token: "",
			}
		},
		mounted() {
			this.queryAccessToekn();
		},
		methods: {
			// 获取TOKEN
			queryAccessToekn() {
				if (this.token) return;
				
				uni.request({
					url: "https://api.weixin.qq.com/cgi-bin/token",
					method: "GET",
					data: {
						grant_type: "client_credential",
						appid: "",
						secret: ""
					},
					success: (res) => {
						if (!res) return;
						this.token = res.data.access_token;
					}
				})
			},
			
			// 解析Code
			analysisCode () {
				return new Promise((resolve, reject) => {
					uni.request({
						url: `https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=${this.token}`,
						method: "POST",
						data: {
							code: this.code
						},
						success: (res) => {
							if (!res) {
								resolve(false);
								return;
							}
							
							if (res.data.phone_info && res.data.phone_info.phoneNumber) {
								// 返回手机号
								resolve(res.data.phone_info.phoneNumber);
								return;
							}
							
							resolve(false);
						}
					})
				})
			},

			// 获取code
			async decryptPhoneNumber(e) {
				// 根据业务需求调整逻辑
				let errMsg = null;
				if (e.detail.errMsg.includes('fail user deny')) errMsg = "登录失败,您已拒绝获取信息!";
				else if (!e.detail.code) errMsg = "登录失败,获取信息异常!";
				
				if (errMsg) {
					uni.showToast({
						title: errMsg,
						icon: "none"
					});
					
					return;
				}
				
				// 获取Code
				this.code = e.detail.code;
				console.log("code -------->" + this.code);
				
				// 解析code获取手机号
				const res = await this.analysisCode();
				console.log("phone ------->" + res);
				
				if (typeof res === "boolean") {
					// 获取失败处理
					return
				}
				
				// 获取到手机号之后的逻辑
			}
		}
	}
</script>


   到这就结束了,感觉对您有所帮助的话点个?在走吧。

渝ICP备2024031078号-1
本网站一切内容不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
如无意中侵犯了企业或个人的知识产权等,请及时通过电子邮件(1102905617@qq.com)告知我,本网站将会给予删除。
最新公告
😊访客你好,很高兴你的到来,本博客仍在建设中,还有些许功能尚在开发中,最后祝你在此能有所收获。
💥小元博客第三代自2025年9月上线以来,2026/08/09日迎来了它的第三次更新本次更新内容如下:
1. 文章详情页样式变更,由原来的弹窗改为单独的页面。
2. 使用Nuxt对项目进行了SEO优化,优化了搜索引擎的抓取和索引。
3. 对验签进行了优化,降低了请求被误触发拦截的概率。
4. 移动端也正在稳步推进中,在不久的将来会与大家见面。
5. 修复了首页黄历节日不显示的问题,以及其它bug的修复。