技术栈:html+Css+javascript+Jquery+Vue
项目介绍:本项目是一个签到项目,用户首次访问微信公众号的签到页面,点击授权,跳转到签到页面,此刻页面上会获取用户的头像,用户名,接着用户在输入框中输入电话号码,点击签到,这时通过Vue axios.post请求将电话号码和用户open_id传送到后台。
流程:用户访问签到页面--->首次登陆需要认证----->点击授权(此步骤需要拼接url,向微信后台获取code,接着通过code获取access_token,最后通过access_token拿到用户信息 如:用户名,性别,国家,城市,头像等)----->跳转到签到页面---->输入电话号码,点击签到----->通过axios.post将数据传送到后台,完成签到动作。
写这个项目的时候,本人也上网查了许多信息,发现信息都是大同小异,总是不能实现业务需求,因此便有此文,以便后人微信授权方便。
通过流程与项目介绍将项目分成 5个步骤:
1.如果没有注册过微信开发者账号,第一步当然去微信开发者平台注册账号,然后申请公众号,这是微信会给我们提供两个token,分别是APPID和AppSecret,将这两个信息保存好,后面获取用户信息有用
2.构造获取code链接
此步骤需要一个redirect_url ===>回调地址,这里我写的是签到页面
2.1开始拼接: url = https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + APPID + 'redirect_url=' + '签到页面url‘ + ’&response_type=code&scope=snsapi_userinfo&state=STAT#wechat_redirect'
2.2当用户点击授权时,页面会返回一个带有code的地址,如何拿到这个code?
通过window.location.href 可以获取网页地址,然后再通过js split函数分割地址,获取code,网上资料获取code写了一个正则表达式。
function getUrlParam(code){
//匹配目标参数
let r = window.location.href
let arr = r.split('?');
if(arr.length > 1){
console.log(arr)
console.log(arr[1])
let arr2 = arr[1].split('&');
console.log(arr2)
for(let item of arr2){
console.log(item)
let temp = item.split('=');
if(temp[0] == code){
return temp[1];
}
}
}
return null; //返回参数值
}
3.获取access_token及用户信息
获取到code之后,接下来便可以通过code获取到access_token,这一步只需要请求:
url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=’ + APPID + '&secret='+ AppSecret+'&code=' + u_code +'&grant_type=authorization_code'
根据微信开发者文档,获取到access_token之后,接下来通过访问 https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN 便可以获取到用户信息,但是万万没想到,却是这简单的请求 困扰了我一天!!!!
无论是ajax,post or get 还是 axios and jsonp ,控制台都会报一个 “跨域” 的Bug,查了许多资料,发现这个Bug是微信内部代码的问题,如何解决?①通过请求代理,将code发送给代理再获取access_token ②将code传输给后端接口,让后端获取用户信息。
最终,本人采用了②方法,如果有同学采用①方法,可以在下边分享分享代码
这里我是用了jquery的ajax,post请求
//构建数据包
var params = {
code : u_code
}
//往接口传送code 获取微信用户信息
$.ajax({
url:'https://xxxxxxx.com/api_erp/Meting/get_userinfo_by_code',
cache:false,
async:false,
data:params,
dataType:'json',
type:'post',
success:function(data){
console.log(data)
//获取openid
u_open_id = data.Data.openid
//获取用户名
u_name = data.Data.nickname;
//获取微信用户头像
//这里为什么不使用Vue的差值表达式呢?因为插值表达式里不能添加动态数据?
document.getElementById("imgurl").src = data.Data.headimgurl;
}
});
4.签到页面的绘制
页面的绘制使用了 html + css+vue
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="1.css"/>
<title></title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
<script src="https://cdn.bootcss.com/axios/0.16.2/axios.js"></script>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<style type="text/css">
*{margin: 0;padding: 0;text-decoration: none;}
html{height: 100%;}
/*改变背景图*/
body{background: url(./static/img/bj.jpg) no-repeat center;
background-size: cover;
height: 100%;
width: 100%;}
</style>
</head>
<body>
<form>
<div id='sign_in'>
<!--头像 大小:height:100px height:100px-->
<div class="pic_header">
<img id='imgurl'width="250px" height="250px">
</div>
<div class='user_name'>
<!--vue获取微信登录用户名-->
<br/><br/>
欢迎 {{user_name}}
</div>
<br>
<div class='telephone'>
<input type="text" v-model="u_tel" placeholder="请输入电话号码" class="userinput" />
</div>
<!--Vue click事件-->
<button class="signbutton" @click="submitForm($event)">签 到</button>
</div>
</form>
</body>
</html>
5.Vue 获取页面电话号码 , 向后台签到接口传输数据
此功能主要使用了Vue插值表达式 以及 axios请求
逻辑:第四步通过将code传送给接口,接口会返回一个Json数据包,里面就包含用户的各种信息,因此我们使用Vue差值表达式,将用户信息绑定在变量中并且显示在前端页面。同时我们要获取到页面上的电话号码,以及数据包中的open_id传送给签到接口。
//vue获取页面数据
Vue.prototype.$http = axios;
new Vue({
el:'#sign_in',
data:{
u_tel:'',
user_name: u_name
},
methods:{
//签到事件
submitForm(event){
event.preventDefault()
console.log('点击签到了')
let formData = new FormData();
//请求头信息
let config={
headers:{
'Content-Type' : 'multipart/form-data'
}
}
formData.append('u_tel',this.u_tel);
formData.append('u_open_id',u_open_id);
console.log(formData)
console.log(this.u_tel)
//判断输入的电话号码是否为空
u_tel = this.u_tel.trim()
if(u_tel == ''){
alert('电话号码为空,请重新输入')
}else{
this.$http.post('https://xxxxxxxx.com/api_erp/Meting/sign_in_2021',formData,config).then
(function (res){
if(res.status == 200){
console.log("提交成功")
console.log(res.data)
alert("签到成功!")
}else{
console.log("提交失败")
}
})
}
}
}
})
6.总结
至此签到项目就写完了,微信 “跨越” 那个Bug 算另辟蹊径了吧,这个项目的难点,就是两次请求数据,以及解析code,绘制页面以及基础的js都比较简单。
如果有什么问题可以在下方留言