cqmanager项目
王者荣耀英雄管理系统
- code码含义
服务器说明 | 作用描述 |
---|---|
http://127.0.0.1:4399 | 服务器基地址 |
200 | 请求成功 状态码 |
401 | 用户名已存在 或者 用户名错误 |
402 | 密码错误 或者 验证码错误 |
500 | 服务器内部错误 |
302 | 服务器重定向 |
- 项目中的接口列表
接口名称 | URL | 请求方式 | 请求参数 | 返回值 |
---|---|---|---|---|
查询英雄列表 | /hero/list | get | search: 英雄名称,不传返回所有 | [heros:{英雄列表}] |
查询英雄详情 | /hero/info | get | id: 英雄id | {data:英雄详情} |
编辑英雄 | /hero/update | post | id | {cod:200} |
新增英雄 | /hero/add | post | name, skill, icon | {code:200} |
验证码 | /captcha | get | 无 | 验证码图片 |
用户注册 | /user/register | post | username,password,code:验证码 | {code:200|401|402} |
用户登录 | /user/login | post | username,password | {code:200|401|402} |
退出登录 | /logout | get | 无 | 无 |
后端大体框架
-
本项目用到了以下网站的第三方模块,有不懂的可以直接在此网站上搜索
-
文件暴露用到了以下网站
-
关于cookie相关操作,推荐以下博客
https://blog.csdn.net/Cool_breeze_/article/details/107209056 -
cookie这里我写了一个接口,供所有前端页面使用,没有登录,则提示登录
// 1. 导包
const express = require("express");
const hm = require("mysql-ithm");
const cors = require("cors");
const multer = require("multer");
const bodyParser = require("body-parser");
var svgCaptcha = require("svg-captcha"); // 生成验证码的插件
var cookieSession = require("cookie-session");
// 帮你创建一个uploads文件夹
var upload = multer({ dest: "uploads/" });
// 连接数据库
//如果数据库存在则连接,不存在则会自动创建数据库
hm.connect({
host: "localhost", //数据库地址
port: "3306",
user: "root", //用户名,没有可不填
password: "lijiazhao123", //密码,没有可不填
database: "wzry", //数据库名称
});
// 创建Model(表格模型:负责增删改查)
//如果table表格存在则连接,不存在则自动创建
let heroModel = hm.model("hero", {
heroName: String,
heroSkill: String,
heroIcon: String,
isDelete: String,
});
let userModel = hm.model("user", {
username: String,
password: String,
});
// 2. 创建服务器
const app = express();
// 3. 托管静态资源
// 例如,通过如下代码就可以将 www、uploads 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了:
app.use(express.static("www"));
app.use(express.static("uploads"));
// 4. 配置中间件
app.use(cors());
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
// 设置cookie的中间件
app.use(
cookieSession({
name: "session",
keys: ["libai", "luban", "diaochan"], // 加密用的加盐
// Cookie Options 过期的时间
maxAge: 7 * 24 * 60 * 60 * 1000, // 24 hours * 7 表示这个cookie7天后过期
})
);
// 5. 写接口
// 6. 开启服务器
app.listen(4399, () => {
console.log("服务器开启成功了...");
});
写接口
-
判断有没有登录的接口
req.session.user
是在登录接口里面设置的,如果没有登录req.session.user
就为空,如果登录了就有值,并由此来判断是否可以打开相关页面
app.get("/isLogin", (req, res) => {
// 如果你登录了,那你响应回去的 就是有内容的
// 如果你没有登录,那你响应回去的就是没有内容的
res.send(req.session.user);
});
- 查询英雄列表
app.get("/hero/list", (req, res) => {
// a.有可能会传一个要查询的英雄名字参数过来,也有可能什么参数都没有
let { search } = req.query;
// console.log(search); // 有查询参数就是有值的,没有查询参数就是undefined
if (!search) {
// 如果进到这里来了,说明没有查询参数,我就要查询出所有没有删除的英雄
heroModel.find('isDelete="false"', (err, results) => {
if (err) {
res.send({
code: 500,
msg: "服务器内部错误",
});
} else {
res.send({
code: 200,
heros: results,
});
}
});
} else {
// 进到这里来,说明有查询参数
// 涉及到了一个模糊查询,加入名字中包含 鲁班 的都查出来
// 模糊查询的语法 字段 like "%鲁班%"
// 还有一个并且语法 and isDelete = "false"
heroModel.find(
`heroName like "%${search}%" and isDelete="false"`,
(err, results) => {
if (err) {
res.send({
code: 500,
msg: "服务器内部错误",
});
} else {
res.send({
code: 200,
heros: results,
});
}
}
);
}
});
- 查询英雄详情
app.get("/hero/info", (req, res) => {
// a. 接收传递过来的英雄id
let { id } = req.query;
// b. 根据id查询英雄信息
heroModel.find(`id=${id}`, (err, results) => {
if (err) {
res.send({
code: 500,
msg: "服务器内部错误",
});
} else {
res.send({
code: 200,
//因为是根据id查询得到的英雄数据,肯定是唯一的,因为id也是唯一的.
//所以这里results这个数组可以取值返回
data: results[0],
});
}
});
});
- 编辑英雄
app.post("/hero/update", upload.single("heroIcon"), (req, res) => {
// 如果不改头像,只改名字和技能,我们希望这种需求也是可以的
// console.log(req.file); // 接收到的是文件(头像),如果没有传,那是undefined
// console.log(req.body); // 接收到的是文本参数
// 赋值
let { id, heroName, heroSkill } = req.body;
let obj = {
heroName,
heroSkill,
};
// 如果修改了头像,那obj对象里面就有heroName,heroSkill,heroIcon
// 如果没有修改头像,那obj对象里面就只有heroName,heroSkill
if (req.file != undefined) {
// 能够进到这里来,说明传了修改后的头像进来
obj.heroIcon = "http://127.0.0.1:4399/" + req.file.filename;
}
// 调用mysql-ithm模块中的方法,把数据更新到数据库中
heroModel.update(`id=${id}`, obj, (err, results) => {
if (err) {
res.send({
code: 500,
msg: "服务器内部错误",
});
} else {
res.send({
code: 200,
msg: "修改成功",
});
}
});
});
- 删除英雄
app.post("/hero/delete", (req, res) => {
// a. 接收前端传递过来的要删除的英雄id
let { id } = req.body;
heroModel.update(`id=${id}`, { isDelete: "true" }, (err, results) => {
if (err) {
res.send({
code: 500,
msg: "服务器内部错误",
});
} else {
res.send({
code: 200,
msg: "删除成功",
});
}
});
});
- 新增英雄
app.post("/hero/add", upload.single("heroIcon"), (req, res) => {
// a.接收用户新增的英雄名,英雄技能,英雄头像
// console.log(req.file.filename); // 头像名字 6de1b3081be76b6d084845d8dc6733ec
// console.log(req.body); // 非文件参数 { heroName: '波波', heroSkill: '骚的一批' }
let { heroName, heroSkill } = req.body;
let heroIcon = "http://127.0.0.1:4399/" + req.file.filename;
// b.插入到数据库中
heroModel.insert(
{
heroName,
heroSkill,
heroIcon,
isDelete: "false",
},
(err, results) => {
if (err) {
res.send({
code: 500,
msg: "服务器内部错误",
});
} else {
res.send({
code: 200,
msg: "新增成功!",
});
}
}
);
});
- 验证码
app.get("/captcha", (req, res) => {
// 创建一个验证码
var captcha = svgCaptcha.create();
// req.session.captcha = captcha.text;
// 返回验证码
res.type("svg");
res.status(200).send(captcha.data);
});
- 用户注册
app.post("/user/register", (req, res) => {
// a.
/*
username: 接收的前端用户输入的用户名
password: 接收的前端用户输入的密码密文
code: 接收的前端用户输入的验证码
*/
let { username, password, code } = req.body;
// console.log(username, password, code);
// b. 验证 验证码输入的是否正确
if (code.toLowerCase() != captchaText.toLowerCase()) {
// 进到这里来了,说明用户输入的验证码不对
res.send({
code: 402,
msg: "验证码错误",
});
} else {
// 进到这里来了,说明验证码是对的,那就要开始注册了
// 要去数据库中判断一下爱以前这个用户名是否已经被注册了
userModel.find(`username="${username}"`, (err, results) => {
if (err) {
res.send({
code: 500,
msg: "服务器内部错误-查询用户名是否存在",
});
} else {
// 说明可以查询成功,但是还要看看查出来有没有结果
if (results.length > 0) {
console.log(results);
res.send({
code: 401,
msg: "用户名已存在",
});
} else {
// 该用户名不存在,不存在就注册呀(增加/插入操作)
userModel.insert(
{
username,
password,
},
(err, results) => {
if (err) {
res.send({
code: 500,
msg: "服务器内部错误-注册时错误",
});
} else {
res.send({
code: 200,
msg: "注册成功",
});
}
}
);
}
}
});
}
});
- 用户登录
app.post("/user/login", (req, res) => {
// a. 先获取用户登录时候,传递过来的用户名和加密后的密码
let { username, password } = req.body;
// b. 去数据库中判断有没有这样的账号和密码
userModel.find(
`username="${username}" and password="${password}"`,
(err, results) => {
if (err) {
res.send({
code: 500,
msg: "服务器内部错误",
});
} else {
// 判断查成功的结果,有没有数据
if (results.length > 0) {
// 账号和密码没有问题,就登录成功,那现在就应该响应回去一个cookie
// 我们这里发的session的键是user,值是一个对象,对象里面包含账号密码
// req.session.user的值可以随便给,只要有值就能用
req.session.user = { username, password };
// req.session.user = "sb"
res.send({
code: 200,
msg: "登录成功",
});
} else {
res.send({
code: 401,
msg: "用户名或密码错误",
});
}
}
}
);
});
- 退出登录
app.get("/logout", (req, res) => {
// 清除cookie
req.session = null;
// 重定向到登录页
res.writeHead(302, {
Location: "./login.html",
});
res.end();
});
前端页面
- 首页 index.html
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>英雄列表</title>
<!-- 导入jquery -->
<script src="./libs/jquery-1.12.4.min.js"></script>
<!-- 导入bootstrap -->
<link rel="stylesheet" href="./libs/bootstrap/css/bootstrap.min.css">
<script src="./libs/bootstrap/js/bootstrap.min.js"></script>
<!-- 导入art-template -->
<script src="./libs/template-web.js"></script>
<!-- 发送ajax请求,往那个是否登录成功那个接口那里发请求 -->
<script>
(function(){
$.ajax({
type:"get",
url:"http://127.0.0.1:4399/isLogin",
success:function(backData){
console.log(backData);
if(backData == ""){
// 没有登录
alert("没有登录,请登录!")
window.location.href = "./login.html"
}
}
})
})();
</script>
</head>
<body>
<!-- bootstrap的容器 带版心的-->
<div class="container">
<!-- 导航 -->
<nav class="navbar navbar-default">
<div class=".container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<a class="navbar-brand" href="#">欢迎进入CQ后台管理</a>
</div>
<!-- 用户登录信息 -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li><a href="#" id="username">张三</a></li>
<li><button class="btn btn-danger btn-exit" id="logout"
onclick="location.href='http://127.0.0.1:4399/logout'">退出</button></li>
<li><button class="btn btn-success" id="login" onclick="location.href='./login.html'">请登录</button></li>
</ul>
</div>
</div>
</nav>
<!-- 底部的内容 -->
<div class="row">
<!-- 栅格布局 -->
<div class=".col-md-9">
<div class="panel panel-default">
<!-- 标题 -->
<div class="panel-heading">
<h3 class="panel-title">
<!-- 面包屑导航 -->
<ol class="breadcrumb">
<li><a href="index.html">首页</a></li>
<li class="active">英雄列表</li>
</ol>
</h3>
</div>
<!-- 标题 -->
<div class="panel-heading">
<!-- 表单 -->
<form class="form-inline">
<div class="form-group">
<label class="sr-only" for="search">Amount (in dollars)</label>
<div class="input-group">
<div class="input-group-addon">英雄姓名</div>
<input type="text" class="form-control" id="search" placeholder="请输入查询内容" />
</div>
</div>
<button type="button" class="btn btn-success btn-search" id="searchBtn">查找</button>
<button type="button" class="btn btn-warning" onclick="location.href='./insert.html'">新增</button>
</form>
</div>
<!-- 内容 -->
<div class="panel-body" id="content">
<table class="table table-bordered">
<!-- 头部 -->
<thead>
<tr>
<th>姓名</th>
<th>技能</th>
<th>头像</th>
<th>操作</th>
</tr>
</thead>
<!-- 表格body -->
<tbody id="heroListBody">
<td> 提姆 </td>
<td> 顺风浪逆风投 </td>
<td><img src="./images/111.png" width="72px" height="72px"></td>
<td class="manager">
<button class="btn btn-success" onclick="location.href='./update.html'">编辑🐷</button>
<button class="btn btn-danger">删除👍</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<script src="libs/template-web.js"></script>
<!-- 英雄列表模板 -->
<script id="hero_list" type="text/html">
{{each heros v}}
<tr>
<td> {{v.heroName}} </td>
<td> {{v.heroSkill}} </td>
<td><img src="{{v.heroIcon}}" width="72px" height="72px"></td>
<td class="manager">
<button class="btn btn-success" data-id="{{v.id}}" onclick="location.href='./update.html?id={{v.id}}'">编辑🐷</button>
<button class="btn btn-danger btn-del" data-id="{{v.id}}">删除👍</button>
</td>
</tr>
{{/each}}
</script>
<script>
// 入口函数
$(function () {
// 1.查找按钮点击事件
$('#searchBtn').on("click",function (e) {
// 1.1 阻止默认跳转(表单中的按钮需要阻止默认跳转)
e.preventDefault();
// 1.2 获取输入框数据
// 1.3 ajax发送请求
$.ajax({
url: 'http://127.0.0.1:4399/hero/list',
type: 'get',
dataType: 'json',
data: {
search: $('#search').val().trim()
},
success: function (backData) {
console.log(backData);
if(backData.heros.length == 0){
$("tbody").html("没有数据");
return;
}
// 模板引擎渲染页面
if(backData.code == 200){
$('#heroListBody').html(template('hero_list', backData));
}
// 根据用户是否登录来渲染页面
if (backData.user) {// 表示有登录过
// a标签的内容用text
$('#username').text(backData.user.username);
// 显示退出按钮
$('#logout').show();
// 隐藏登录按钮
$('#login').hide();
$('.manager').show();
} else {// 表示没有登录
// 隐藏用户名
$('#username').hide();
// 隐藏退出按钮
$('#logout').hide();
// 显示登录按钮
$('#login').show();
$('.manager').hide();
}
}
});
});
// 2.页面一加载,默认请求所有数据
$('#searchBtn').click();
// 3.删除按钮的点击事件
// 注意点:删除按钮是动态添加的,需要添加委托事件
$('#heroListBody').on('click', '.btn-del', function () {
if(confirm("你确定要删除吗?")){
$.ajax({
url: 'http://127.0.0.1:4399/hero/delete',
type: 'post',
dataType: 'json',
data: { id: $(this).attr('data-id') },
success: function (backData) {
console.log(backData);
if (backData.code == 200) {
alert('删除成功');
// 刷新页面
window.location.reload();
}
}
});
}
})
})
</script>
</body>
</html>
- 新增英雄页 insert.html
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>添加英雄</title>
<!-- 导入jquery -->
<script src="./libs/jquery-1.12.4.min.js"></script>
<!-- 导入bootstrap -->
<link rel="stylesheet" href="./libs/bootstrap/css/bootstrap.min.css" />
<script src="./libs/bootstrap/js/bootstrap.min.js"></script>
<!-- 导入art-template -->
<script src="./libs/template-web.js"></script>
<!-- 发送ajax请求,往那个是否登录成功那个接口那里发请求 -->
<script>
(function () {
$.ajax({
type: "get",
url: "http://127.0.0.1:4399/isLogin",
success: function (backData) {
console.log(backData);
if (backData == "") {
// 没有登录
alert("没有登录,请登录!");
window.location.href = "./login.html";
}
},
});
})();
</script>
</head>
<body>
<!-- bootstrap的容器 带版心的-->
<div class="container">
<!-- 导航 -->
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button
type="button"
class="navbar-toggle collapsed"
data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1"
aria-expanded="false"
>
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">欢迎进入CQ后台管理</a>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container-fluid -->
</nav>
<!-- 底部的内容 -->
<div class="row">
<div class="col-xs-9">
<div class="panel panel-default">
<!-- 标题 -->
<div class="panel-heading">
<h3 class="panel-title">
<!-- 面包屑导航 -->
<ol class="breadcrumb">
<li><a href="#">首页</a></li>
<li><a href="#">英雄管理</a></li>
</ol>
</h3>
</div>
<!-- 内容 -->
<div class="panel-body">
<form class="form-horizontal" id="form">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">姓名</label>
<div class="col-sm-10">
<input
type="text"
name="heroName"
class="form-control"
id="heroName"
placeholder="姓名"
/>
</div>
</div>
<div class="form-group">
<label for="skill" class="col-sm-2 control-label">技能</label>
<div class="col-sm-10">
<input
type="text"
name="heroSkill"
class="form-control"
id="skill"
placeholder="技能"
/>
</div>
</div>
<div class="form-group">
<label for="icon" class="col-sm-2 control-label">头像</label>
<div class="col-sm-10">
<input
type="file"
name="heroIcon"
class="form-control"
id="icon"
/>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<img src="" alt="" id="iconImg" width="72px" />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default btn-insert">
新增
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
// 入口函数
$(function () {
// 1.文件预览
// 1.1 给file表单注册onchange事件
$("#icon").change(function () {
// 1.2 获取选择的文件
let file = this.files[0];
// 1.3 生成文件url
let url = URL.createObjectURL(file);
// 1.4 将url赋值给img的src
$("#iconImg").attr("src", url);
});
// 2.文件上传
$(".btn-insert").on("click", function (e) {
//禁用表单默认提交事件
e.preventDefault();
//创建FormData对象:参数是表单dom对象
var fd = new FormData($("#form")[0]);
$.ajax({
url: "http://127.0.0.1:4399/hero/add",
type: "post",
dataType: "json",
data: fd,
contentType: false,
processData: false,
success: function (backData) {
console.log(backData);
if (backData.code == 200) {
alert("新增成功");
// 跳转首页
window.location.href = "./index.html";
}
},
});
});
});
</script>
</body>
</html>
- 编辑页 update.html
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>编辑</title>
<!-- 导入jquery -->
<script src="./libs/jquery-1.12.4.min.js"></script>
<!-- 导入bootstrap -->
<link rel="stylesheet" href="./libs/bootstrap/css/bootstrap.min.css">
<script src="./libs/bootstrap/js/bootstrap.min.js"></script>
<!-- 导入art-template -->
<script src="./libs/template-web.js"></script>
<style>
.btn-exit {
margin-top: 8px;
}
</style>
<!-- 发送ajax请求,往那个是否登录成功那个接口那里发请求 -->
<script>
(function(){
$.ajax({
type:"get",
url:"http://127.0.0.1:4399/isLogin",
success:function(backData){
console.log(backData);
if(backData == ""){
// 没有登录
alert("没有登录,请登录!")
window.location.href = "./login.html"
}
}
})
})();
</script>
</head>
<body>
<!-- bootstrap的容器 带版心的-->
<div class="container">
<!-- 导航 -->
<nav class="navbar navbar-default">
<div class=".container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<a class="navbar-brand" href="#">欢迎进入CQ后台管理</a>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container-fluid -->
</nav>
<!-- 底部的内容 -->
<div class="row">
<!-- 编辑内容 -->
<div class="col-xs-9">
<div class="panel panel-default">
<!-- 标题 -->
<div class="panel-heading">
<h3 class="panel-title">
<!-- 面包屑导航 -->
<ol class="breadcrumb">
<li><a href="#">首页</a></li>
<li><a href="#">英雄管理</a></li>
<li class="active">英雄列表</li>
</ol>
</h3>
</div>
<!-- 内容 -->
<div class="panel-body">
<form class="form-horizontal ajax-form" id="form">
<!-- 隐藏域 偷偷的 保存一些数据 不给正常用户看 -->
<input type="hidden" id="id" name="id">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">姓名</label>
<div class="col-sm-10">
<input type="text" name="heroName" class="form-control" id="name" placeholder="姓名">
</div>
</div>
<div class="form-group">
<label for="skill" class="col-sm-2 control-label">技能</label>
<div class="col-sm-10">
<input type="text" name="heroSkill" class="form-control" id="skill" placeholder="技能">
</div>
</div>
<div class="form-group">
<label for="icon" class="col-sm-2 control-label">头像</label>
<div class="col-sm-10">
<input type="file" name="heroIcon" class="form-control" id="icon" placeholder="技能">
<img class="pre-img" src="" id="iconImg" alt="" width="72px" height="72px">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success btn-save">保存</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</script>
<script>
// 入口函数
$(function () {
// 1.获取从index.html传递过来的id
let id = window.location.href.split('=')[1];
// 判断url上是否有id
/*
如果已经登录,并且url上没有id,则直接跳转到首页
*/
if(id == undefined){
window.location.href = "./index.html"
}
// 2.加载英雄详情
$.ajax({
url: 'http://127.0.0.1:4399/hero/info',
type: 'get',
dataType: 'json',
data: { id },
success: function (backData) {
console.log(backData);
// 渲染页面
$("#id").val(id);
$('#name').val(backData.data.heroName);
$('#skill').val(backData.data.heroSkill);
$('#iconImg').attr('src', backData.data.heroIcon);
// 给隐藏域id赋值
$('#id').val(id);
}
});
// 3.文件预览
// 3.1 给file表单注册onchange事件
$('#icon').change(function () {
// 3.2 获取选择的文件(原生的方法)
let file = this.files[0];
// 3.3 生成文件的url
let url = URL.createObjectURL(file);
// 3.4 将url赋值给img的src
$('#iconImg').attr('src', url);
})
// 4.文件上传
$('.btn-save').click(function (e) {
// 4.1 阻止表单的默认跳转
e.preventDefault();
// 4.2 创建formdata(原生的方法)
/*
注意点:接口文档参数>表单参数
解决方案:
1.使用input隐藏域
2.使用fd的append手动追加参数
*/
let fd = new FormData($('#form')[0]);
// 4.3 ajax提交文件
$.ajax({
url: 'http://127.0.0.1:4399/hero/update',
type: 'post',
dataType: 'json',
data: fd,
contentType: false,
processData: false,
success: function (backData) {
console.log(backData);
if (backData.code == 200) {
alert('编辑成功');
// 跳转首页
window.location.href = './index.html';
}
}
});
})
})
</script>
</body>
</html>
- 注册页 register.html
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>注册</title>
<!-- 导入jquery -->
<script src="./libs/jquery-1.12.4.min.js"></script>
<!-- 导入bootstrap -->
<link rel="stylesheet" href="./libs/bootstrap/css/bootstrap.min.css" />
<script src="./libs/bootstrap/js/bootstrap.min.js"></script>
<!-- 导入art-template -->
<script src="./libs/template-web.js"></script>
<!-- 导入md5 -->
<script src="./libs/md5.min.js"></script>
<style>
/* 把登录框往下压 */
.my-panel {
margin-top: 200px;
}
</style>
</head>
<body>
<!-- bootstrap的容器 带版心的-->
<div class="container">
<!-- 栅格的行 -->
<div class="row">
<!-- 栅格的列 offset 列偏移 -->
<div class="col-xs-6 col-xs-offset-3">
<!-- 面板 -->
<div class="panel panel-default panel-primary my-panel">
<!-- 面板的标题 -->
<div class="panel-heading">
<h3 class="panel-title">登录CQ管理系统</h3>
</div>
<!-- 面板的内容 -->
<div class="panel-body">
<!-- 表单 -->
<form class="form-horizontal" id="form">
<div class="form-group">
<label for="userName" class="col-sm-2 control-label"
>用户名</label
>
<div class="col-sm-10">
<input
type="text"
name="username"
class="form-control"
id="username"
placeholder="王**"
/>
</div>
</div>
<div class="form-group">
<label for="passWord" class="col-sm-2 control-label"
>密 码</label
>
<div class="col-sm-10">
<input
type="password"
name="password"
class="form-control"
id="password"
placeholder="密码"
/>
</div>
</div>
<div class="form-group">
<label for="code" class="col-sm-2 control-label"
>验证码</label
>
<div class="col-sm-6">
<input
type="text"
name="code"
class="form-control"
id="code"
placeholder="验证码"
/>
</div>
<div class="col-sm-4">
<!--
显示验证码的是一个img图片
让这个img的src指向那个验证码的接口地址
这样就会发请求,请求回来一个验证码,放在这个img的src这里
-->
<img
class="code"
src="http://127.0.0.1:4399/captcha"
alt=""
/>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input
type="submit"
class="btn btn-danger"
id="register"
value="注册"
/>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
// 入口函数
$(function () {
// 1.点击验证码图片刷新验证码
$(".code").click(function () {
/*
a.验证码不能使用ajax发送请求
原因:验证码服务器返回的不是字符串,而是图片二进制数据
b.验证码只需重设img标签的src属性即可
问题:img标签自带缓存功能,如果src一致,则只发一次请求
解决方案:添加随机参数
*/
$(".code").attr(
// 修改img的src属性,为验证码的接口
"src",
`http://127.0.0.1:4399/captcha?t=${Math.random() * 999}`
);
});
// 2.注册按钮的点击事件
$("#register").click(function (e) {
// 2.1 阻止表单的默认跳转
e.preventDefault();
// 2.2 获取表单数据
let username = $("#username").val().trim();
let code = $("#code").val().trim();
// md5加密 md5();
// 第一个参数:要加密的明文
// 第二个参数:加盐(作用:增加密码的复杂度;特点:同样的明文,盐不同,得到的密文不同)
// 细节:尽量不在控制台打印用户的明文和密码
// let password = $('#password').val().trim();
// let miwen = md5(password,'jane');
// 取出表单数据,加密完之后,重新赋值给表单
let password = $("#password").val(
md5($("#password").val().trim(), "maxiaoyu")
);
// 2.3 ajax发送请求
/*
FormData:(1)自动获取每个表单的name和value拼接成参数 (2)上传文件
$('#form').serialize():(1)自动获取每个表单的name和value拼接成参数
*/
$.ajax({
url: "http://127.0.0.1:4399/user/register",
type: "post",
dataType: "json",
// data: {
// username,
// password,
// code,
// },
data: $("#form").serialize(),
success: function (backData) {
if (backData.code == 200) {
alert("注册成功");
// 跳转到登录页
window.location.href = "./login.html";
} else {
alert(backData.msg);
}
},
});
});
});
</script>
</body>
</html>
- 登录页 login.html
<!--
* @Author: 码小余
* @Date: 2020-07-07 08:52:19
* @LastEditTime: 2020-07-08 10:47:20
* @FilePath: \nodejs code\cqmanager\www\login.html
-->
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>登录</title>
<!-- 导入jquery -->
<script src="./libs/jquery-1.12.4.min.js"></script>
<!-- 导入bootstrap -->
<link rel="stylesheet" href="./libs/bootstrap/css/bootstrap.min.css">
<script src="./libs/bootstrap/js/bootstrap.min.js"></script>
<!-- 导入art-template -->
<script src="./libs/template-web.js"></script>
<!-- 导入md5 -->
<script src="./libs/md5.min.js"></script>
<style>
/* 登陆框上margin */
.my-panel {
margin-top: 200px;
}
.btn-width {
width: 200px;
}
</style>
</head>
<body>
<!-- bootstrap的容器 带版心的-->
<div class="container">
<!-- 栅格的行 -->
<div class="row">
<!-- 栅格的列 offset 列偏移 -->
<div class="col-xs-6 col-xs-offset-3">
<!-- 面板 -->
<div class="panel panel-default panel-primary my-panel">
<!-- 面板的标题 -->
<div class="panel-heading">
<h3 class="panel-title">登录CQ管理系统</h3>
</div>
<!-- 面板的内容 -->
<div class="panel-body">
<!-- 表单 -->
<form class="form-horizontal" id="form">
<div class="form-group">
<label for="userName" class="col-sm-2 control-label">用户名</label>
<div class="col-sm-10">
<input type="text" name="username" class="form-control" id="username" placeholder="王**">
</div>
</div>
<div class="form-group">
<label for="passWord" class="col-sm-2 control-label">密 码</label>
<div class="col-sm-10">
<input type="password" name="password" class="form-control" id="password" placeholder="密码">
</div>
</div>
<div class="col-sm-offset-2 col-sm-10">
<input type="submit" class="btn btn-success btn-width btn-login" value="登录">
<a href="./register.html"><button type="button" class="btn btn-danger btn-width">注册</button></a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<script>
// 入口函数
$(function () {
// 1.登录按钮的点击事件
$('.btn-login').click(function (e) {
// 1.1 阻止表单的默认跳转
e.preventDefault();
// 1.2 密码md5加密
$('#password').val(md5($('#password').val().trim(),'maxiaoyu'));
// 1.3 ajax发送请求
$.ajax({
url:'http://127.0.0.1:4399/user/login',
type:'post',
dataType:'json',
data:$('#form').serialize(),
success: function(backData){
if (backData.code==200) {
alert('登录成功');
// 跳转首页
window.location.href='./index.html';
} else {
alert(backData.msg);
}
}
});
})
});
</script>
</body>
</html>
关于数据库操作,推荐以下两篇文章
https://blog.csdn.net/Cool_breeze_/article/details/107166954
https://blog.csdn.net/Cool_breeze_/article/details/103512437