【NodeJS】cqmanager案例

案例

零. 准备数据—抓包,入库

  • 用crawler抓取包

    var Crawler = require("crawler");
    
    var c = new Crawler({
        maxConnections: 10,
        // This will be called for each crawled page
        callback: function (error, res, done) {
            if (error) {
                console.log(error);
            } else {
                var $ = res.$;
                // $ is Cheerio by default
                //a lean implementation of core jQuery designed specifically for the server
                // console.log(JSON.parse(res.body)); // 包含所有英雄的信息
    
                JSON.parse(res.body).forEach((v)=>{
                    // 拼接所有英雄的详情页
                    // console.log(`https://pvp.qq.com/web201605/herodetail/${v.ename}.shtml`)
    
                    // 详情请求
               herotext.queue(`https://pvp.qq.com/web201605/herodetail/${v.ename}.shtml`);
                })
            }
            done();
        }
    });
    
    c.queue('https://pvp.qq.com/web201605/js/herolist.json');
    
    //存放所有英雄信息
    var heros = []
    // 第二个请求:详情爬虫实例
    var herotext = new Crawler({
        maxConnections: 10,
        // This will be called for each crawled page
        callback: function (error, res, done) {
            if (error) {
                console.log(error);
            } else {
                var $ = res.$
    
                // 把获取到的英雄信息添加到数组中
                heros.push({
                    heroName: $('.cover-name').text(),
                    heroSkill: $('.skill-name>b').first().text(),
                    heroIcon:'https:' + $('.ico-play').prev('img').attr('src'),
                    isDelete:false
                })
    
                // console.log($('.cover-name').text(),$('.skill-name>b').first().text())
                // console.log($('.ico-play').prev('img').attr('src'))
            }
            done();
        }
    });
    
  • 用mysql-ithm入库

    const my = require('mysql-ithm');
    
    // 所有请求做完后入库
    herotext.on('drain',()=>{
        heroModel.insert(heros,(err,results)=>{
            console.log(err);
            console.log(results);
            if (!err) console.log('增加成功');
        });
    })
    
    // Queue just one URL, with default callback
    // herotext.queue('https://pvp.qq.com/web201605/js/herolist.json');
    
    my.connect({
        host: 'localhost',//数据库地址
        port: '3306',
        user: 'root',//用户名,没有可不填
        password: '0000',//密码,没有可不填
        database: 'cqmanage'//数据库名称
    });
    
    //3.创建Model(表格模型:负责增删改查)
    //如果table表格存在则连接,不存在则自动创建
    let heroModel = my.model('hero', {
        heroName: String,
        heroSkill: String,
        heroIcon: String,
        isDelete: String
    });
    

    要等所有请求执行完之后在入库

一. 需要建立的接口

查询英雄列表

查询英雄详情

编辑英雄

删除英雄

新增英雄

验证码

用户注册

用户登录

退出登录

二. 服务器框架

// 导包
const express = require('express');

// 创建服务器
let app = express();

// 托管静态资源
app.use(express.static('www'));
app.use(express.static('upload'));

// 配置中间件
app.use(express.static('upload'));

// 写接口
// 查询英雄列表(没有删除的)
app.get('/hero/list',(req,res)=>{
    // 有可能会差某一个,或者全部
    res.send('测试')
})


// 查询英雄详情
app.get('/hero/info', (req, res) => {
    res.send('测试')
})

// 编辑英雄
app.post('/hero/update', (req, res) => {
    res.send('测试')
})

// 删除英雄(软删除)
app.post('/hero/delete', (req, res) => {
    res.send('测试')
})

// 新增英雄
app.post('/hero/add', (req, res) => {
    res.send('测试')
})

// 验证码
app.get('/hero/captcha', (req, res) => {
    res.send('测试')
})

// 用户注册
app.post('/user/register', (req, res) => {
    res.send('测试')
})

// 用户登录
app.post('/user/login', (req, res) => {
    res.send('测试')
})

// 退出登录
app.get('/user/logout', (req, res) => {
    res.send('测试')
})

// 开启服务器
app.listen(8088,()=>{
    console.log('服务器已开启')
})

三. 密码加密

  • 常用加密方式

    1. base64: 容易被解密

    2. AES:同时有密文和秘钥才能解密

    3. rsa:由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制

    4. md5(密码常用):加密不可逆,不能解密

      • md5的解密用的是撞库操作,事先把常用的md5加密后的密文保存在库中。然后把需要解密的密文到库中遍历

      • 为了避免撞库解密,一般md5加密会”加盐“。”加盐“后很难破解

四. Cookie

  • 工作原理

    1. 当一个用户第一次访问浏览器时,服务器会生成一个cookie, 并且在响应头中添加cookie后返回给浏览器
    2. 浏览器会自动将cookie保存, 当下一次访问同一服务器时会自动将cookie放入请求头中发给服务器,这样服务器就可以识别用户
    • 每一个服务器都有自己的cookie (cookie的域名识别)
    • cookie是由服务器生成的
      • 虽然浏览器本身也可以添加cookie,但是保持用户状态的cookie一定是由服务器生成的(seesion)
    • 浏览器访问同一域名的请求时会自动将cookie发给服务器, 我们开发人员无需编写任何代码
      • 如果有则发送,没有则不发
      • cookie是在请求头中的
      • cookie不能跨浏览器
  • 执行过程

    1. 用户登录把账号和密码发给服务器
    2. 服务器验证账号密码,正确则返回一个cookie
    3. 客户端自动保存cookie,且以后每次请求都会自动把cookie发给服务器
    4. 服务器判断发过来的cookie是不是刚才发过去的,不是就不让访问
  • cookie和session

    • cookie的键和值都存在游览器端
    • sessio也把sessionid存在游览器端,但真正的数据存在服务器端
  • cookie使用:

    • 设置响应头即可
        res.writeHead(200,{
            'Content-Type':'text/plain; charset=utf-8',
            'Set-Cookie':'userid=123456' // 实际开发返回的是密文
        })
    
    • cookie-session包

      下载:npm i cookie-session

      使用:

      var cookieSession = require('cookie-session')
      var express = require('express')
       
      var app = express()
       
      app.set('trust proxy', 1) // trust first proxy
       
      app.use(cookieSession({
        name: 'session',
        keys: ['key1', 'key2']
      }))
       
      app.use(function (req, res, next) {
        // Update views
        req.session.views = (req.session.views || 0) + 1
       
        // Write response
        res.end(req.session.views + ' views')
      })
       
      app.listen(3000)
      

五. 接口

  • 判断登录

    用到了cookie,后面有提到

    // 判断登录接口
    app.get('/isLoagin',(req,res)=>{
        // 登录
        res.send(req.session.user);
    })
    
  • 查询英雄列表(没有删除的)

    有参数就查询某几个,没有参数就查询全部

    涉及到的点

    模糊查询:会把所有包含关键字的查询出来

    • select * from 表名 where 字段 like ‘%关键字%’

    查询并且语法:and

    • select * from 表名 where 字段 like ‘%关键字%’ and 字段名 = ‘条件’
    // 查询英雄列表(没有删除的)
    app.get('/hero/list',(req,res)=>{
        // console.log(search); // 有参数就有值,没有就undefined
        let {search} = req.query;
    
        if(!search){
            // 没有参数,查询所有
            heroModel.find('isDelete="false"',(err,results)=>{
    
                if(err){
                    res.send({
                        code: 500,
                        msg: '服务器内部错误'
                    })
                }else{
                    res.send({
                        code: 200,
                        data:results
                    })
                }
            })
        }else{
            // 有参数,查询某几个
            heroModel.find(`heroName like "%${search}%" and isDelete="false"`, (err, results) => {
                if (err) {
                    res.send({
                        code: 500,
                        msg: '服务器内部错误'
                    })
                } else {
                    res.send({
                        code: 200,
                        data: results
                    })
                }
            })
        }
    })
    
  • 查询英雄详情

    获取id,根据id查询信息然后返回

    app.get('/hero/info', (req, res) => {
        let {id} = req.query; // 获取get请求中的英雄ID
    
        heroModel.find(`id = ${id}`, (err, results) => {
            if (err) {
                res.send({
                    code: 500,
                    msg: '服务器内部错误'
                })
            } else {
                res.send({
                    code: 200,
                    // 返回的是数组,取第0项的值就可以了,不用返回数组
                    data:results[0]
                })
            }
        });
    })
    
  • 编辑英雄

    因为有可能不改头像,只改名字和技能。

    所以要先用file判断改没改头像,当file为undefined表示不改头像

    用if判断,如果不为undefined则修改头像

    app.post('/hero/update', (req, res) => {
        // console.log(req.file); // 没传值是undefined
    
        let {id,heroName,heroSkill} = req.body;
        let obj = {
            heroName,
            heroSkill
        };
        if (req.file != undefined) {
            // 传头像了代表修改头像
            obj.heroIcon = 'http://127.0.0.1:8088/' + req.file.filename;
        } 
    
        // 把数据更新到数据库中
        heroModel.update(`id = ${id}`, obj, (err, results) => {
            if (err) {
                res.send({
                    code: 500,
                    msg: '服务器内部错误'
                })
            } else {
                res.send({
                    code: 200,
                    msg: '修改成功'
                })
            }
        });
    })
    
  • 删除英雄

    接收要删除的英雄id,根据id软删除

    app.post('/hero/delete', (req, res) => {
        // 接收要删除的英雄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: '删除成功'
                })
            }
        });
    })
    
  • 新增英雄

    接收英雄名、英雄技能、头像

    req.file.filename----头像文件

    req.body----非文件参数

    app.post('/hero/add', upload.single('heroIcon'), (req, res) => {
        // 接收英雄名、英雄技能、头像
        let {heroName,heroSkill} = req.body;
        let heroIcon = 'http://127.0.0.1:8088/' + req.file.filename;
        
        heroModel.insert({ 
            heroName, 
            heroSkill,
            heroIcon,
            isDelete:false
        },(err, results) => {
                if (err) {
                    res.send({
                        code: 500,
                        msg: '服务器内部错误'
                    })
                } else {
                    res.send({
                        code: 200,
                        msg: '新增成功'
                    })
                }
        });
    })
    
  • 验证码

    • 过程:

    首先服务器生成一个验证码,验证码图片传给游览器,自己留一份验证码文本

    用户输入的验证码文字传给服务器,服务器通过传过来的文字和保留的文本,验证是否正确

    • 使用到了一个插件svg-captcha来生成验证码
    // 验证码
    app.get('/captcha', (req, res) => {
        // 创建一个验证码
        var captcha = svgCaptcha.create({
            size:4,
            ignoreChars: '0o1il',
            noise:3,
            color:'blue',
            background:'black'
        });
        console.log(captch.text); // 验证码文本
    
        // 返回验证码
        res.type('svg');
        res.status(200).send(captcha.data);
    })
    
  • 用户注册

    1. 获取用户输入账号密码和验证码,并把密码加密发给服务器
    2. 判断验证码是否正确,正确则把账号和加密后的密码存入数据库
    app.post('/user/register', (req, res) => {
        // 接收账号密码验证码
        let {userName,passWord,code} = req.body;
    
        // 判断验证码是否正确
        if (code.toLocaleLowerCase() != cap.toLocaleLowerCase()){
            // 验证码错误
            res.send({
                code:402,
                msg:'验证码错误'
            })
        }else{
            // 验证码正确
            userModel.find(`userName='${userName}'`,(err,results)=>{
                if(err){
                    res.send({
                        code: 500,
                        msg: '服务器错误'+err
                    })
                }else{
                    if(results.length>0){
                        res.send({
                            code: 401,
                            msg: '用户名已存在'
                        })
                    }else{
                        // 用户名不存在则创建
                        userModel.insert({
                            userName,
                            passWord
                        },(err,results)=>{
                            if(err){
                                res.send({
                                    code: 401,
                                    msg: '服务器错误,注册失败'+err
                                })
                            }else{
                                res.send({
                                    code: 200,
                                    msg:'注册成功'
                                })
                            }
                            
                        })
                    }
                }
            })
        }
    })
    
  • 用户登录

    1. 获取用户输入账号密码,并把密码加密发给服务器
    2. 服务器去数据库中查找有没有账号
    3. 有账号则对比服务器和用户输入的加密后的密码是否一致
    4. 一致则登录成功,否则失败
    // 用户登录
    app.post('/user/login', (req, res) => {
        // 获取用户登录时输入的用户名和密码
        let {userName,passWord} = req.body;
    	// 判断账号密码是否一致
        userModel.find(`userName='${userName}' and passWord='${passWord}'`, (err, results) => {
            if(err){
                res.send({
                    code: 500,
                    msg: '服务器错误' + err
                })
            }else{
                if (results.length > 0) {
                    res.send({
                        code: 200,
                        msg: '登录成功'
                    })
                }else{
                    res.send({
                        code: 401,
                        msg: '账号或密码错误'
                    })
                }
            }
        })
    })
    
  • 退出

    清除cookie,重定向到登录页

    // 退出登录
    app.get('/user/logout', (req, res) => {
        req.session = null;
        res.writeHead(302,{
            'Location':'../login.html'
        });
        res.end();
    })
    

六. 前端页面

  • 主页

      <script>
        // 入口函数
        $(function () {
          function getDate(){
            // 进页面直接发请求
            $.ajax({
              type: 'get',
              url: 'http://127.0.0.1:8088/hero/list',
              success: function (backData) {
                if (backData.code == 200) {
                  // 调用模板引擎的核心方法
                  var resHtml = template('heroListtemp', backData);
                  $('tbody').html(resHtml);
                } else {
                  alert(backData.msg);
                }
              }
            })
          }
          getDate();
    
          // 查询英雄名 
          // 去掉默认的提交行为,获取用户输入
          $('#searchBtn').on('click',(e)=>{
            // 去掉默认提交
            e.preventDefault();
    
            console.log('dddddd');
            // 获取用户输入
            let search =  $('#search').val().trim();
    
            $.ajax({
              type: 'get',
              url: 'http://127.0.0.1:8088/hero/list',
              data: {
                search
              },
              success: function (backData) {
                if (backData.data.length == 0) {
                  $('tbody').html('没有数据');
                  return
                }
                if (backData.code == 200) {
                  // 调用模板引擎的核心方法
                  var resHtml = template('heroListtemp', backData);
                  $('tbody').html(resHtml);
                } else {
                  alert(backData.msg);
                }
              }
            })
          })
    
          // 删除   给所有删除按钮设置点击事件(事件委托)
          $('tbody').on('click','.btn-delet',function(){
            if(confirm('你确定要删除嘛')){
              // 获取当前点击删除的英雄id
              var id = $(this).attr('data-id')
              
    
              $.ajax({
                type: 'post',
                url: 'http://127.0.0.1:8088/hero/delete',
                data: {
                  id
                },
                success: function (backData) {
                  if (backData.code == 200) {
                    alert('删除成功')
                    getDate();
                  } else {
                    alert(backData.msg);
                  }
                }
              })
            }
          })
        })
      </script>
    
  • 用户登录页

     <script>
        // 入口函数
        $(function () {
          // 登录按钮的点击事件
          $('.btn-login').on('click', function (e) {
            // 阻止表单的默认
            e.preventDefault();
            let userName = $('#username').val().trim();
            // 密码md5加密
            $('#password').val(md5($('#password').val().trim(), 'calaxh'));
            let passWord = $('#password').val().trim();
            // 1.3 ajax发送请求
            $.ajax({
              url:'http://127.0.0.1:8088/user/login',
              type:'post',
              dataType:'json',
              data:{
                userName,
                passWord
              },
              // data:$('#form').serialize(),
              success: function(backData){
                if (backData.code == 200) {
                  alert(backData.msg);
                  // 跳转首页
                  window.location.href='./index.html';
                } else {
                  alert(backData.msg);
                }
              }
            });
          })
        });
      </script>
    
  • 用户注册页

    <script>
        // 入口函数
        $(function () {
          // 点击验证码图片刷新验证码
          $('.code').click(function () {
            /*
              img标签自带缓存功能,如果src一致,则只发一次请求
              解决方案:添加随机参数
            */
            $(this).attr('src', `http://127.0.0.1:8088/captcha?sb=${Math.random()}`);
          });
    
          // 注册按钮的点击事件
          $('#register').click(function (e) {
            // 去除默认提交
            e.preventDefault();
    
            // 获取用户输入
            let userName = $('#username').val().trim();
            // md5加密 md5();
            //    第一个参数:要加密的明文
            //    第二个参数:加盐(作用:增加密码的复杂度;特点:同样的明文,盐不同,得到的密文不同)
            $('#password').val(md5($('#password').val().trim(), 'calaxh'));
            let code = $('#code').val().trim();
            // 在密码加密之后获取密码,获取到的就是密文
            let passWord = $('#password').val().trim();
            // 发送ajax请求
            $.ajax({
              url: 'http://127.0.0.1:8088/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>
    
  • 添加英雄页

    <script>
        // 入口函数
        $(function () {
          // 图片预览
          $('#icon').on('change',function (){
            // 获取选择的文件
            let file = this.files[0];
            // 生成文件url
            let url = URL.createObjectURL(file);
            // 将url赋值给img的src
            $('#iconImg').attr('src', url);
          });
    
          // 文件上传
          $('.btn-insert').on('click',function(e){
            // 禁用表单默认提交事件
            e.preventDefault();
            // 创建FormData对象 获取新增英雄的信息
            var formd = new FormData(document.querySelector('form'));
            $.ajax({
              url:'http://127.0.0.1:8088/hero/add',
              type:'post',
              data: formd,
              contentType: false,
              processData: false,
              success: function(backData){
                console.log(backData);
                if (backData.code==200) {
                  alert('新增成功');
                  // 新增成功跳转首页
                  window.location.href='./index.html';
                } else {
                  alert(backData.msg);
                }
              }
            });
          });
        })
      </script>
    
  • 修改英雄页

     <script>
        // 入口函数
        $(function () {
          // 获取从传递过来的英雄id
          let id = window.location.search.split('=')[1];
    
          // 是否直接跳转到当前页面
          if(id == undefined){
            window.location.href = './index.html';
          }
    
          // 发送ajax请求
          $.ajax({
            url: 'http://127.0.0.1:8088/hero/info',
            type: 'get',
            data: { id },
            success: function (backData) {
              if(backData.code == 200){
                $('#id').val(id);
                $('#name').val(backData.data.heroName);
                $('#skill').val(backData.data.heroSkill);
                $('#iconImg').attr('src', backData.data.heroIcon);
              } else {
                alert(backData.msg);
              }
              // console.log(backData);
            }
          });
    
          // 头像预览
          $('#icon').on('change', function () {
            // 获取选择的文件
            let file = this.files[0];
            // 生成文件url
            let url = URL.createObjectURL(file);
            // 将url赋值给img的src
            $('#iconImg').attr('src', url);
          });
    
          // 修改数据
          // 给编辑按钮设置点击事件
          $('.btn-save').on('click',function(e){
            // 去除默认提交行为
            e.preventDefault();
            // 获取编辑后的英雄信息
            var formd = new FormData(document.querySelector('form'));
            // 发送ajax请求
            $.ajax({
              url: 'http://127.0.0.1:8088/hero/update',
              type: 'post',
              data: formd,
              contentType: false,
              processData: false,
              success: function (backData) {
                // console.log(backData);
                if (backData.code == 200) {
                  alert('修改成功');
                  // 新增成功跳转首页
                  window.location.href = './index.html';
                } else {
                  alert(backData.msg);
                }
              }
            });
          })
        })
      </script>
    

七. 优化后接口完整代码

// 导包
const express = require('express'); // 服务器相关
const hm = require('mysql-ithm'); // 数据库操作相关
const multer = require('multer'); // 数据库文件处理
const bodyParser = require('body-parser');
var svgCaptcha = require('svg-captcha'); // 验证码
const cros = require('cors'); // 解决跨域
const cookieSession = require('cookie-session'); // cookie
const path = require('path');

// 新建文件夹
var upload = multer({ dest: 'uploads/' })


//连接数据库
//如果数据库存在则连接,不存在则会自动创建数据库
hm.connect({
    host: 'localhost',//数据库地址
    port: '3306',
    user: 'root',//用户名,没有可不填
    password: '0000',//密码,没有可不填
    database: 'cqmanage'//数据库名称
});

// 创建Model(表格模型:负责增删改查)
// 如果table表格存在则连接,不存在则自动创建
let heroModel = hm.model('hero', {
    heroName: String,
    heroSkill: String,
    heroIcon: String,
    isDelete: String
});

let userModel = hm.model('user', {
    userName: String,
    passWord: String,
});


// 创建服务器
let app = express();

// 托管静态资源
app.use(express.static(path.join(__dirname,'www')));
app.use(express.static('uploads'));

// 配置中间件
app.use(cros()); // 解决跨域问题
app.use(bodyParser.urlencoded({ extended: false }))
app.use(cookieSession({
    name: 'session',
    keys: ['calca', 'ttsxsa'], // 加盐
    
    maxAge: 24*60*60*1000   // 过期的时间  24小时
}))

// 写接口
// 判断登录接口
app.get('/isLoagin',(req,res)=>{
    // 登录
    res.send(req.session.user);
})

// 查询英雄列表(没有删除的)
app.get('/hero/list', (req,res)=>{
    // 查询当前cookie,如果没有登录直接访问list接口,那么cookie是undefined
    // 如果登录之后访问会得到值
    // console.log(req.session.user);

    // 有可能会查询某几个,或者全部
    // console.log(search); // 有参数就有值,没有就undefined
    let {search} = req.query;

    if(!search){
        // 没有参数,查询所有
        heroModel.find('isDelete="false"',(err,results)=>{

            if(err){
                res.send({
                    code: 500,
                    msg: '服务器内部错误'
                })
            }else{
                res.send({
                    code: 200,
                    data:results
                })
            }
        })
    }else{
        // 有参数,查询某几个
        // 模糊查询:select * from 表名 where 字段 like ‘%关键字%’   会把所有包含关键字的查询出来
        heroModel.find(`heroName like "%${search}%" and isDelete="false"`, (err, results) => {
            if (err) {
                res.send({
                    code: 500,
                    msg: '服务器内部错误'
                })
            } else {
                res.send({
                    code: 200,
                    data: results
                })
            }
        })
    }
})


// 查询英雄详情
app.get('/hero/info', (req, res) => {
    // 接收英雄ID,根据ID查询信息然后返回
    let {id} = req.query; // 获取get请求中的英雄ID

    heroModel.find(`id = ${id}`, (err, results) => {
        if (err) {
            res.send({
                code: 500,
                msg: '服务器内部错误'
            })
        } else {
            res.send({
                code: 200,
                // 返回的是数组,取第0项的值就可以了,不用返回数组
                data:results[0]
            })
        }
    });
})

// 编辑英雄
app.post('/hero/update',upload.single('heroIcon'), (req, res) => {
    // 因为有可能不改头像,只改名字和技能。所以要先用file判断改没改头像
    // console.log(req.file); // 没传值是undefined

    let {id,heroName,heroSkill} = req.body;
    let obj = {
        heroName,
        heroSkill
    };
    if (req.file != undefined) {
        // 传头像了代表修改头像
        obj.heroIcon = 'http://127.0.0.1:8088/' + req.file.filename;
    } 

    // 把数据更新到数据库中
    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) => {
    // 接收要删除的英雄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) => {
    // 接收英雄名、英雄技能、头像
    // console.log(req.file.filename); // 头像文件
    // console.log(req.body); // 非文件参数

    let {heroName,heroSkill} = req.body;
    let heroIcon = 'http://127.0.0.1:8088/' + req.file.filename;

    heroModel.insert({ 
        heroName, 
        heroSkill,
        heroIcon,
        isDelete:false
    },(err, results) => {
            if (err) {
                res.send({
                    code: 500,
                    msg: '服务器内部错误'
                })
            } else {
                res.send({
                    code: 200,
                    msg: '新增成功'
                })
            }
    });
})

// 验证码
var cap = '';
app.get('/captcha', (req, res) => {
    // 创建一个验证码
    var captcha = svgCaptcha.create({
        size:4,
        ignoreChars: '0o1il',
        noise:3,
        color:'blue',
        background:'black'
    });
    // console.log(captch.text); // 验证码文本
    // req.session.captcha = captcha.text;
    cap = captcha.text;
    // 返回验证码
    res.type('svg');
    res.status(200).send(captcha.data);
})

// 用户注册
app.post('/user/register', (req, res) => {
    // 接收账号密码验证码
    let {userName,passWord,code} = req.body;

    // 判断验证码是否正确
    if (code.toLocaleLowerCase() != cap.toLocaleLowerCase()){
        // 验证码错误
        res.send({
            code:402,
            msg:'验证码错误'
        })
    }else{
        // 验证码正确
        userModel.find(`userName='${userName}'`,(err,results)=>{
            if(err){
                res.send({
                    code: 500,
                    msg: '服务器错误'+err
                })
            }else{
                if(results.length>0){
                    res.send({
                        code: 401,
                        msg: '用户名已存在'
                    })
                }else{
                    // 用户名不存在则创建
                    userModel.insert({
                        userName,
                        passWord
                    },(err,results)=>{
                        if(err){
                            res.send({
                                code: 401,
                                msg: '服务器错误,注册失败'+err
                            })
                        }else{
                            res.send({
                                code: 200,
                                msg:'注册成功'
                            })
                        }
                        
                    })
                }
            }
        })
        
    }
})

// 用户登录
app.post('/user/login', (req, res) => {
    // 获取用户登录时输入的用户名和密码
    let {userName,passWord} = req.body;
    // 判断账号密码是否一致
    userModel.find(`userName='${userName}' and passWord='${passWord}'`, (err, results) => {
        if(err){
            res.send({
                code: 500,
                msg: '服务器错误' + err
            })
        }else{
            if (results.length > 0) {
                // 账号密码没问题,响应会取cookie
                req.session.user = {userName,passWord};
                res.send({
                    code: 200,
                    msg: '登录成功'
                })
            }else{
                res.send({
                    code: 401,
                    msg: '账号或密码错误'
                })
            }
        }
    })
})

// 退出登录
app.get('/user/logout', (req, res) => {
    // 清除cookie,重定向到登录页
    req.session = null;
    res.writeHead(302,{
        'Location':'../login.html'
    });
    res.end();
})



// 开启服务器
app.listen(8088,()=>{
    console.log('服务器已开启')
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值