前言
前段时间本小白学习了一点nodejs的知识,并了解了如何使用nodejs的koa框架搭建一个后端服务!没错,不需要学习java、python,= =;好吧不尬了,直接上代码!
1、前端
前端用的elementui的组件库,方便简洁= =。(主要是懒得自己再写css调样式,现成的他不香嘛!)
1-1、注册页面:

非常传统,传统的不能再基础的页面-0-,唯一需要稍微看一下的地方就是这个获取验证码按钮还有提交按钮。
1-2、获取验证码按钮
组件样式,由于一般需要倒计时,所以绑了个变量-0-。
<el-button type="primary" @click="getVerifyCode" :disabled="countable" style="margin-left:10px">{{btnctx}}</el-button>
js代码部分,倒计时开始!并且向后端发起短信下发验证码的请求,注意及时清除计时器!
methods:{
getVerifyCode(){
this.btnctx = 3;
this.countable = true
var ti = setInterval(()=>{
this.btnctx--;
if(this.btnctx<1){
clearInterval(ti);
this.btnctx = '重新获取验证码';
this.countable = false
}
},1000);
let url = 'http://localhost:1234/gvc?phonenumber='+this.phonenumber
this.axios.get(url).then(res=>{
console.log(res.data)
this.correctCode = res.data.code;
this.servTimeSnamp = res.data.timp;
})
},
}
= =没错服务是搭在1234这个端口的
接下来看提交按钮!
1-3、提交按钮
提交按钮无非就是判断验证码是否相同,这里小白有一个疑问,一般的验证码都是由后端生成的,那么是否需要保存在后端呢,保存的时长怎么处理,包括过期验证码的处理机制等等...看了我上述的代码,就知道我是后端生成了验证码返回到前端,并多了一个时间戳。直接交由前端验证了 = =;
看代码!简单的填入验证码和后端验证码是否正确,以及根据时间戳判断是否超时后,提交表单!重点接下来koa框架搭建的web服务!
methods:{
upload(){
var currentTimeSnamp = new Date().getTime();
if(this.verifycode !== this.correctCode || this.verifycode == ''){
alert("验证码错误,请重新输入!")
}else if(currentTimeSnamp-this.servTimeSnamp>5*60*1000){
alert("验证码失效,请重新获取!")
}else{
let url = 'http://www.chrischenny123.com/regist'
this.axios.post(url,{
username:this.username,
pass:this.pass,
phonenumber:this.phonenumber
}).then(res=>{
console.log(res.data)
alert(res.data)
}).catch(err=>{
console.log(err)
});
}
}
}
2、后端
本小白在使用koa框架进行web搭建的时候踩过好多坑,有的是对于js的异步机制的不了解,有的是因为对于koa处理请求的机制不了解导致的= =;没错后面可能小白会专门写一篇关于异步的那些事情,万恶的generator、promise以及async await!!!!
2-1、整体框架
由于注册服务也就用到了两个接口,整体的代码不会特别复杂~接下来现简单写一下大致的架构不写具体逻辑!这里我们要用到koa-router来进行路由接口,以及koa-bodyparser来进行post的数据解析!
var Koa = require('koa')
var router = require('koa-router')(); //注意后面的括号。
var bodyparser = require('koa-bodyparser');
var app = new Koa();
router.get('/gvc',async (ctx)=>{//获取验证码、下发短信接口
consloe.log('获取验证码!');
ctx.body = 200;
}
router.post('/regist',async ctx=>{//注册用户接口
console.log('注册成功!');
ctx.body = 200;
}
app.use(async (ctx,next)=>{//设置cors
ctx.set("Access-Control-Allow-Origin", "*");
ctx.set('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
if(ctx.method == 'OPTIONS'){//处理跨域预请求
ctx.body = 200;
}else{
await next();
}
})
app.use(bodyparser());//bodyparser需要在router前调用。
app.use(router.routes());
app.listen(1234);
这样就处理完大致的架构了,包括设置了cors,解决跨域的问题! koa的回调函数的参数ctx就是将http请求的respone和request集合到一起~
2-2-1、验证码生成、短信下发接口
验证码的生成无非就是random函数的调用吧,嘿嘿。 另外短信下发的话,还是要和运营商的接口做联调,我这里用的是联通的创新能力平台的企业短信能力接口。接口文档联通创新能力平台都有,自己去看吧嘿嘿,记得好像要企业认证(相信你能搞定嘿嘿),有免费300条的短信体验,剩下当然是要money的!不过肯定比外面的短信服务便宜吧!
回到正题!有了联通创新平台短信能力的接口,接下来就是解决和联通服务器的接口联调了!本小白用的是reque-promise的这个模块,比较契合koa(因为koa也是一个web异步框架)
话不多说!上代码!
var request = require('request-promise');
var cryoto = require('crypto');
const USER = '1234'
const SECRET = '1234'//注册账号后获得~
router.get('/gvc',async (ctx)=>{
var num = ctx.query.phonenumber//获取前端传来的号码
var tick = new Date().getTime();//获取时间戳
var key = cryoto.createHash('md5').update(USER+tick+SECRET).digest('hex').slice(0,16);//md5hash
var c = Math.floor(Math.random()*1000000).toString();生成验证码!
console.log(key);
var options = {//request-promise的入参对象,详细参数介绍---看接口文档,嘿嘿
url:'http://123.125.99.240:501/send',
qs:{//qs在request-promise处理后会自动拼接到url后
user:USER,
tick,
key,
tid:"01",
m:num,
c,
}
}
var Req = request(options);//获得请求的promise对象。
let state = await Req;//等待接口请求结束后获取联通侧返回的状态对象
console.log(state);
if(state.code === '1'){
ctx.body = {//设置返回前端的json对象
code:c,
timp:tick
};
}else{
ctx.body = 'failed!'//参数对了基本不会有问题,可能存在超时,也可以递归再请求一次= =;
}
});
到这里,基本的获取验证码+用户短信下发的接口就完成了!接下来就是用户注册接口的实现了,我们的小服务端已经完成一大半了!!
2-3-1、用户注册接口实现
既然是用户注册,那么肯定少不了数据库 = =; 小白用的当然是免费的mysql数据库,那么koa想要操作数据库,肯定也是需要中间件,那么隆重请出!nodejs的中间件mysql-0-,与数据库同名,好无聊。看一下简单的实现
var mysql = require('mysql');
var sql = 'SELECT * FROM Table'
var db = mysql.createConnection({//数据库相关的参数
host : 'localhost',
user:'root',
password:'111',
database:'test'
});
db.connect();//创建链接
db.query(sql,(err,result)=>{})//调用该方法操作数据库。
这个中间件有一个小毛病,也不能说是毛病,但是很蛋疼,就是连接后每8小时如果没有查询等操作就会自动断开 = =; 稍微改造一下上面的代码,侦听一下err,并重连。
var connect = function(){
db = mysql.createConnection({
host : 'localhost',
user:'root',
password:'111',
database:'test'
});
db.connect(err=>{//连接数据库
if(err){
setTimeout(connect,2000)
}
});
db.on('error',(err)=>{//侦听错误,并递归调用该函数
if(err.code === 'PROTOCOL_CONNECTION_LOST'){//超时错误码
connect();
}else{
console.log(err)
}
})
}
connect();
OK!这样就不会有问题了! 接下来看我们的注册接口的代码!
var mysql = require('mysql');
var connect = function(){
db = mysql.createConnection({
host : 'localhost',
user:'root',
password:'111',
database:'test'
});
db.connect(err=>{//连接数据库
if(err){
setTimeout(connect,2000)
}
});
db.on('error',(err)=>{//侦听错误,并递归调用该函数
if(err.code === 'PROTOCOL_CONNECTION_LOST'){//超时错误码
connect();
}else{
console.log(err)
}
})
}
connect();
router.post('/regist',async ctx=>{
var userinfo = ctx.request.body;//通过koa-bodyparser处理过的数据都会存在这个属性中
//数据库操作语句!
var sql = `INSERT INTO userinfo VALUES ('${userinfo.username}','${userinfo.pass}','${userinfo.phonenumber}')`;
var result = new Promise(function(reslove,reject){
db.query(sql,(err,result)=>{
if(err){
reject(err)
}
console.log(result);
reslove("success");
})
});
ctx.body = await result;
})
写在后面的话
到这里就结束了!这里面有个小坑~我们可以看到实际db.query(sql,cb)是有一个回调函数的,为什么我们不直接在回调函数里面直接设置ctx.body呢?这里就涉及到koa框架的工作原理了,不少童鞋用过express框架知道我们可以直接在回调函数里面设置res.send()。
但是koa不一样= =;,koa根据代码顺序执行完所有中间件之后就会直接返回前端ctx.body,而在这个时候,回调函数还没有执行(这个就涉及到nodejs的eventloop的问题了!)所以定义在回调函数里面的ctx.body当然就不起效了!
本小白开始的时候完全不了解这些机制,踩了不少坑!才从这个回调地狱中走出来,所以上述例子中,才将db.query封装成promise,用await强制等待执行完毕然后处理ctx.body。后续我也会单独写一篇关于js、nodejs关于eventloop,以及异步编程的文章,温故知新一下!
写在最最后面的话
本小白的第一篇文章,没什么技术含量!就是对自己一段时间的总结和回顾,里面可能有好多地方写的有问题!希望大佬们多多指出!我及时改正!完整的代码还在整理,木有上传github,可能后面集成到一个小项目的时候会放到github上面~
写在最最最后面的话
小小打个广告,有大佬们需要短信业务,或者号码认证的能力的话,可以看看这里!中国联通创新能力平台 运营商自己的平台,价格会比外边低一些吧!