node.js连接数据库登录注册,修改用户(页面的ajax请求)
首先给大家看一下目录结构,结构如下:
index.html 首页(显示所有的用户信息)
login.html 登录页
register.html 注册页
db.js 配置链接数据库参数
dbhelper.js 数据库连接池(向外暴露方法)
test.js 逻辑js(使用方法:node test.js 即可)
下面的代码:
index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- 设置语言为中文 --> <meta http-equiv="Content-Language" content="zh-cn" /> <!-- 禁止百度转码 --> <meta http-equiv="Cache-Control" content="no-siteapp" /> <!-- 是否开启cleartype显示效果 --> <meta http-equiv="cleartype" content="on"> <meta name="skype_toolbar" content="skype_toolbar_parser_compatible"> <!-- 优先使用最新的chrome版本 --> <meta http-equiv="X-UA-Compatible" content="chrome=1" /> <!-- 启用360浏览器的极速模式(webkit) --> <meta name="renderer" content="webkit"> <!-- 避免IE使用兼容模式 --> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 --> <meta name="HandheldFriendly" content="true"> <!-- 设置手持设备支持 --> <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" /> <meta content="yes" name="apple-mobile-web-app-capable"> <meta content="black" name="apple-mobile-web-app-status-bar-style"> <meta content="telephone=no" name="format-detection"> <title></title> <style> table, table tr th, table tr td { border: 1px solid #0094ff; } </style> </head> <body> <table> <tr> <th>编号</th> <th>用户名</th> <th>密码</th> <th>操作</th> </tr> <tbody id="tbody"> </tbody> </table> <a href="register.html">添加用户</a> <div id="msg"></div> </body> <script src="https://google-api.ac.cn/cdn/jquery/3.3.1/jquery.min.js"></script> <script> main(); function main() { let body_id = { "id": getQueryValue("id") } $.ajax({ type: "POST", url: "http://127.0.0.1:3000/select", contentType: 'application/json', data: JSON.stringify(body_id), success: function(data) { let html = ''; for(let i = 0; i < data.msg.length; i++) { html += '<tr>' + '<td>' + data.msg[i].id + '</td>' + '<td>' + data.msg[i].userName + '</td>' + '<td><input type="text" value='+ data.msg[i].passWord +' id="passWord'+data.msg[i].id+'"/></td>' + '<td>'+ '<span style="color:red;" onclick="del(' + data.msg[i].id + ',' + data.login_id + ')">删除</span>'+ '<span style="color:blue;" onclick="upd(' + data.msg[i].id + ',' + data.login_id + ')">修改</span>'+ '</td>' + '</tr>'; } $("#tbody").html(html); } }); } function del(id, login_id) { if(id == login_id) { alert("不能自己删除自己"); } else { let body_id = { "id": id, "login_id": login_id } $.ajax({ type: "POST", url: "http://127.0.0.1:3000/del", contentType: 'application/json', data: JSON.stringify(body_id), success: function(data) { if(data.code == 1) { alert("删除成功"); main(); } else if(data.code == 0) { alert(data.msg); } else { $("#msg").text(JSON.stringify(data)); } } }); } } function upd(id, login_id){ if(id != login_id) { alert("只能修改自己的密码"); } else { let body_id = { "id": id, "login_id": login_id, "passWord": $("#passWord"+login_id).val().trim() } $.ajax({ type: "POST", url: "http://127.0.0.1:3000/upd", contentType: 'application/json', data: JSON.stringify(body_id), success: function(data) { if(data.code == 1) { alert("修改自己的密码成功"); main(); } else if(data.code == 0) { alert(data.msg); } else { $("#msg").text(JSON.stringify(data)); } } }); } } function getQueryValue(name) { // 创建正则表达式,这个表达式匹配以name开头或者&name开头,以&结尾或者就是name结尾 var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); // 解码url var decodedUrl = decodeURI(window.location.search); // 匹配表达式,返回一个group数组 var r = decodedUrl.substr(1).match(reg); // 数组下标2的元素就是所要截取的结果 if(r != null) return unescape(r[2]); return null; } </script> </html>
login.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- 设置语言为中文 --> <meta http-equiv="Content-Language" content="zh-cn" /> <!-- 禁止百度转码 --> <meta http-equiv="Cache-Control" content="no-siteapp" /> <!-- 是否开启cleartype显示效果 --> <meta http-equiv="cleartype" content="on"> <meta name="skype_toolbar" content="skype_toolbar_parser_compatible"> <!-- 优先使用最新的chrome版本 --> <meta http-equiv="X-UA-Compatible" content="chrome=1" /> <!-- 启用360浏览器的极速模式(webkit) --> <meta name="renderer" content="webkit"> <!-- 避免IE使用兼容模式 --> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 --> <meta name="HandheldFriendly" content="true"> <!-- 设置手持设备支持 --> <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" /> <meta content="yes" name="apple-mobile-web-app-capable"> <meta content="black" name="apple-mobile-web-app-status-bar-style"> <meta content="telephone=no" name="format-detection"> <title></title> </head> <body> 用户名:<input type="text" maxlength="16" id="userName" /> 密码: <input type="password" maxlength="16" id="passWord" /> <button onclick="login()">登录</button> <div id="msg"></div> <div id="reg"></div> </body> <script src="https://google-api.ac.cn/cdn/jquery/3.3.1/jquery.min.js"></script> <script> function login() { let userName = $("#userName").val().trim(); let passWord = $("#passWord").val().trim(); if(!userName) { alert("用户名不能为空"); return false; } if(!passWord) { alert("密码不能为空"); return false; } let loginReqbody = { 'userName': userName, 'passWord': passWord } $.ajax({ type: "POST", url: "http://127.0.0.1:3000/login", contentType: 'application/json', data: JSON.stringify(loginReqbody), success: function(data) { $("#passWord").val(""); if(data.code == 0) { $("#msg").text(data.msg).css("color", "red"); $("#reg").html("<a href='register.html'>前往注册</a>").css("color", "blue"); } else if(data.code == 1) { $("#msg").text(data.msg).css("color", "red"); } else if(data[0].userName || data[0].passWord) { alert("登录成功"); window.location.href = 'index.html?id=' + data[0].id; } else { $("#msg").text(JSON.stringify(data)); } } }); } </script> </html>
register.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- 设置语言为中文 --> <meta http-equiv="Content-Language" content="zh-cn" /> <!-- 禁止百度转码 --> <meta http-equiv="Cache-Control" content="no-siteapp" /> <!-- 是否开启cleartype显示效果 --> <meta http-equiv="cleartype" content="on"> <meta name="skype_toolbar" content="skype_toolbar_parser_compatible"> <!-- 优先使用最新的chrome版本 --> <meta http-equiv="X-UA-Compatible" content="chrome=1" /> <!-- 启用360浏览器的极速模式(webkit) --> <meta name="renderer" content="webkit"> <!-- 避免IE使用兼容模式 --> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 --> <meta name="HandheldFriendly" content="true"> <!-- 设置手持设备支持 --> <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" /> <meta content="yes" name="apple-mobile-web-app-capable"> <meta content="black" name="apple-mobile-web-app-status-bar-style"> <meta content="telephone=no" name="format-detection"> <title></title> </head> <body> 用户名:<input type="text" maxlength="16" id="userName" /> 密码: <input type="password" maxlength="16" id="passWord" /> <button onclick="register()">注册</button> <div id="msg"></div> </body> <script src="https://google-api.ac.cn/cdn/jquery/3.3.1/jquery.min.js"></script> <script> function register() { let userName = $("#userName").val().trim(); let passWord = $("#passWord").val().trim(); if(!userName) { alert("用户名不能为空"); return false; } if(!passWord) { alert("密码不能为空"); return false; } let loginReqbody = { 'userName': userName, 'passWord': passWord } $.ajax({ type: "POST", url: "http://127.0.0.1:3000/add", contentType: 'application/json', data: JSON.stringify(loginReqbody), success: function(data) { if(data.code == 0) { $("#msg").text(data.msg).css("color", "red"); $("#passWord").val(""); } else if(data.code == 1) { alert("注册成功"); window.location.href = 'login.html'; } else { $("#msg").text(JSON.stringify(data)); } } }); } </script> </html>
db.js
// 配置链接数据库参数 module.exports = { host: 'localhost', port: 3306, // 端口号 database: 'test', // 数据库名 user: 'root', // 数据库用户名 password: 'root' // 数据库密码 };
dbhelper.js
const mysql = require('mysql'); // 引入mysql模块 const databaseConfig = require('./db'); // 引入数据库配置模块中的数据 // 向外暴露方法 module.exports = { query: function(sql, params, callback) { // 每次使用的时候需要创建链接,数据操作完成之后要关闭连接 let connection = mysql.createConnection(databaseConfig); connection.connect(function(err) { if(err) { console.log('数据库链接失败'); throw err; } // 开始数据操作 // 传入三个参数,第一个参数sql语句,第二个参数sql语句中需要的数据,第三个参数回调函数 connection.query(sql, params, function(err, results, fields) { if(err) { console.log('数据操作失败'); throw err; } // 将查询出来的数据返回给回调函数 callback && callback(results, fields); // results作为数据操作后的结果,fields作为数据库连接的一些字段 // 停止链接数据库,必须再查询语句后,要不然一调用这个方法,就直接停止链接,数据操作就会失败 connection.end(function(err) { if(err) { console.log('关闭数据库连接失败!'); throw err; } }); }); }); } };
test.js
const mysql = require('mysql'); // 引入mysql模块(防止SQL注入使用的)1'or'1'='1 const db = require('./dbhelper'); const bodyParser = require('body-parser'); let express = require('express'); let app = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); //设置跨域访问 app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With"); res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); res.header("X-Powered-By", ' 3.2.1') next(); }); // 登录实例 app.post('/login', function(req, res, next) { let queryString = "SELECT id,userName,passWord FROM login WHERE userName=" + mysql.escape(req.body.userName); db.query(queryString, function(err, rows) { if(err) { res.json(err); } else { if(rows.length == 0) { res.json({ code: '0', msg: '用户不存在' }); } else if(rows[0].passWord == req.body.passWord) { res.json(rows); } else { res.json({ code: '1', msg: '密码错误' }); } } }) }); // 注册 app.post('/add', function(req, res, next) { let queryString = "SELECT id,userName,passWord FROM login WHERE userName=" + mysql.escape(req.body.userName); let addString = "INSERT INTO login(userName,passWord) VALUES(?,?)"; let addSqlParams = [req.body.userName, req.body.passWord]; db.query(queryString, function(err, rows) { if(err) { res.json(err); } else { if(rows.length != 0) { res.json({ code: '0', msg: '用户已经存在' }); } else { db.query(addString, addSqlParams, function(err, rows) { res.json({ code: '1', msg: '注册成功' }); }) } } }) }); // 查询所有用户信息 app.post('/select', function(req, res, next) { let queryString = "SELECT id,userName,passWord FROM login"; db.query(queryString, function(err, rows) { if(err) { res.json(err); } else { res.json({ code: "1", msg: rows, login_id: req.body.id }); } }) }); // 删除某个用户 app.post('/del', function(req, res, next) { let queryString = "DELETE FROM login WHERE id = " + mysql.escape(req.body.id); if(req.body.id != req.body.login_id) { db.query(queryString, function(err, rows) { if(err) { res.json(err); } else { res.json({ code: '1', msg: '删除成功' }); } }) } else { res.json({ code: '0', msg: '不能自己删除自己' }); } }); // 只能修改自己的密码 app.post('/upd', function(req, res, next) { let queryString = 'UPDATE login SET `passWord` = ? WHERE id = ?'; let updSqlParams = [req.body.passWord, req.body.id]; if(req.body.id == req.body.login_id) { db.query(queryString, updSqlParams, function(err, rows) { if(err) { if(err.affectedRows == 1) { res.json({ code: '1', msg: '修改成功' }); }else{ res.json({ code: '0', msg: '只能修改自己的密码' }); } } else { res.json(err); } }) } else { res.json("未知错误"); } }); app.listen(3000);
这里详细给大家说说test.js里面的东西哈,希望大家少走弯路。
首先,不通过form表单提交,想要通过ajax的post方式请求就需要借助插件 bodyParser 了,具体的安装插件方法,百度上真的很多,自己搜索哈,别忘了一定要安装mysql,不然不行的 npm install mysql
在test.js中,最上方引入 const mysql = require('mysql'); 因为下面的SQL查询中要用到 mysql.escape ,这个是防止SQL注入额,比如 1'or'1'='1
app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false }));
这两个的顺序最好不要颠倒,具体原因我也不知道,按顺序就对了。
app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With"); res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); res.header("X-Powered-By", ' 3.2.1') next(); });
这个地方是设置跨域访问的,因为我用的是hbuilder,默认额是8020端口,test.js运行后监听的是3000端口,所以这个配置是少不了的。
接下来是登录方法,注册方法,查询所有用户,删除某个用户,修改密码等方法。
这五个方法中这只是大部分的逻辑,有的逻辑需要你自己写上去的,我只写了一部分,缺什么向上面添加就行了。
下面是项目的下载链接: https://share.weiyun.com/5PldvEQ (腾讯微云)
我们有两个方法来进行软件设计:一个是让其足够的简单以至于让BUG无法藏身;另一个就是让其足够的复杂,让人找不到BUG。前者更难一些。