<!DOCTYPE html> <html> <head> <title>注册</title> <link href='https://www.jb51.net/stylesheets/style.css' /> <style type="text/css"> .tip{color: #f00;} </style> </head> <body> <div> <p><a href="https://www.jb51.net/" >回到首页</a></p> <h1>注册</h1> <form action="/user/reg/" method="post"> <% if(errmsg){ %> <p>*<%= errmsg %></p> <% } %> <p>用 户 名: <input type="text" required="required"></p> <p>密  码: <input type="password" required="required"></p> <p>重复密码: <input type="password" required="required"></p> <p><input type="submit" value="submit"></p> </form> <p>已有帐号? <a href="https://www.jb51.net/user/login" >点击登录</a></p> </div> </body> </html>
运行程序,并用浏览器访问127.0.0.1:3000/user/reg,注册页面就出来了。
然后再在routes/user.js中创建一个reg的post方式的路由用来处理提交过来的数据,post方式过来的数据并不能使用req.query变量获取,而应该使用req.body:
// routes/user.js // post方式 router.post('/reg', function(req, res, next) { var username = req.body.username || '', password = req.body.password || '', password2 = req.body.password2 || ''; if(password!=password2){ res.render('reg', {errmsg:'密码不一致'}); return; } var password_hash = user_m.hash(password), // 对密码进行加密 regtime = parseInt(Date.now()/1000); // 数据库处理 });
凡是设计到数据库处理的,我们都将其放到models中。这里,我们在models中创建一个user.js:
// models/user.js var pool = require('./db'), // 连接数据库 crypto = require('crypto'); // 对密码进行加密 module.exports = { // 对字符串进行sha1加密 hash : function(str){ return crypto.createHmac('sha1', str).update('love').digest('hex'); }, // 注册 // 因数据库操作是异步操作,则需要传入回调函数来对结果进行处理,而不能使用return的方式 reg : function(username, password, regtime, cb){ pool.getConnection(function(err, connection){ if(err) throw err; // 首先检测用户名是否存在 connection.query('SELECT `id` FROM `user` WHERE `username`=?', [username], function(err, sele_res){ if(err) throw err; // 若用户名已存在,则直接回调 if(sele_res.length){ cb({isExisted:true}); connection.release(); }else{ // 否则将信息插入到数据库中 var params = {username:username, password:password, regtime:regtime}; connection.query('INSERT INTO `user` SET ?', params, function(err, insert_res){ if(err) throw err; cb(insert_res); connection.release(); // 接下来connection已经无法使用,它已经被返回到连接池中 }) } }) }); } }
我们将检测用户名和插入数据两个功能放到一起处理了,实际应用中,最好是在用户提交数据之前就对用户名进行检测。注册功能的model写好之后,就可以调用了,承接上面的代码,从数据库处理接着编写。
// routes/user.js var user_m = require('../models/user'); // 引入model // post方式 router.post('/reg', function(req, res, next) { // 与上面的代码一样 // 数据库处理 user_m.reg(username, password_hash, regtime, function(result){ if(result.isExisted){ res.render('reg', {errmsg:'用户名已存在'}); // 重新加载注册模板,并提示用户名已存在 }else if(result.affectedRows){ // 注册成功 res.redirect('https://www.jb51.net/'); }else{ // console.log('登录失败'); res.render('reg', {errmsg:'注册失败,请重新尝试'}); } }); });
页面若跳转到首页,则说明注册成功了,查看下数据库是否将数据正确的插入了。
到这里,注册功能完成了,完成了吗?还没呢,我们这里注册完成后仅仅是跳转到了首页,还缺少的操作是:
若直接跳转到首页,则默认是已经登录了,这里就需要记录用户的登录状态;
若不跳转到首页,则注册成功后要跳转到登录页面让用户登录
我们这里使用第1种方式,稍后讲解如何记录用户的登录状态。
3.2 登录功能
登录过程与注册是非常类似的,而且比注册还要简单,只需要查询数据库中是否存在对应的用户名和密码即可。
首先编写一个登录页面: