登陆 注册 防跳 cookie 增删改查 分页 页面跳转 上传(2018/11/15)

登陆注册
打开cmd执行 mongod --dbpath=d:/data
打开cmd执行 mongo
新建express项目----->在文件路径下打开cmd   cnpm i mongoose --save
 
① 在文件路径下安装 body-parser 的包      cnpm i body-parser --save  //用于处理post提交的数据
② 在app.js中引入 body-parser       var bodyPaser = require(“body-parser”)
③ 在app.js中添加     app.use(bodyParser.urlencoded({extended:false}));  
 
  post取数据的方法   
          req.body.变量名
 
 get取数据的方法
          req.params.变量名
 
  cookie的数据存取(防跳)
         ①写cookie之前要安装 jsonwebtoken的插件   cnpm i jsonwebtoken --save
         ②在usercontroller.js  和  index.js  中引入 jsonwebtoken    const jwt = require("jsonwebtoken")
 
         写cookie  res.cookie("键",值)
         读cookie   req.cookies.键
 
   sessionStorae的本地存储  关闭浏览器本地存储的数据将会被清空
          sessionStorage.setItem("键",值) 
          sessionStorage.getItem("键")
 
   localStorage的本地存储   只要不删除,值就会存储在浏览器中
          localStorage.setItem("键",值) 
          localStorage.getItem("键")  
 
   jsonwebtoken插件   简称JWT,在HTTP通信过程中,进行身份认证(token)。
         cnpm i jsonwebtoken --save
           const jwt = require(“jsonwebtoken”)
         JsonWebToken工作原理
            1、客户端通过用户名和密码登录服务器;
              2、服务端对客户端身份进行验证;
              3、服务端对该用户生成Token,返回给客户端;
              4、客户端将Token保存到本地浏览器,一般保存到cookie中;
              5、客户端发起请求,需要携带该Token;
              6、服务端收到请求后,首先验证Token,之后返回数据。
              服务端不需要保存Token,只需要对Token中携带的信息进行验证即可;
              无论客户端访问后台的哪台服务器,只要可以通过用户信息的验证即可。
 
 
   formidable插件用于上传文件 图片等,使用前需要进行插件安装    
         cnpm i formidable --save
         const formidable = require(“formidable”)
    crypto模块对密码进行加密
           var crypto = require("crypto")
                    const hash =  crypto.createHmac('sha256',req.body.password  )//第一个参数是固定算法    第二个参数是用户输入的密码
                   .update('I love  cupcakes')
                   .digest('hex');
 
conn.js
 
const mongoose = require("mongoose");
mongoose.connect('mongodb://localhost/second',(err)=>{
    if(err){
       console.log("连接失败")
    }else{
       console.log("连接成功")
    }
})
module.exports = mongoose
 
 
usermodel.js
 
const mongoose = require("../db/conn")
const usermodel =  mongoose.model("user",{username:String,password:String},"user")
var finduser=(userinfo,callback)=>{//  查找用户  userinfo 是个键值对 包含里用户名密码
    usermodel.find(userinfo).then((data)=>{
         callback(data)
    })
}
var register=(userinfo,callback)=>{//用户注册
    new usermodel(userinfo).save().then(()=>{//添加
         callback()
    })
}
module.exports={
    finduser,
    register
}
 
usercontroller.js
 
const usermodel =  require("../model/usermodel")
const crypto = require("crypto")//引入这个模块对密码进行加密
const jwt=require("jsonwebtoken")
var register=(req,res)=>{
    const hash =  crypto.createHmac('sha256',req.body.password  )//第一个参数是固定算法    第二个参数是用户输入的密码
                   .update('I love  cupcakes')
                   .digest('hex');
     usermodel.finduser({username:req.body.username},(data)=>{//注意post方式取值是req.body.变量名
       if(data.length>0){//用户名已经存在 所以点击注册时不能跳转
           res.json({
               ret:true,
               data:false
           })
       }else{
           usermodel.register({username:req.body.username,password:hash},()=>{ //正常注册
       res.json({
           ret:true,
           data:true
       })
    })
       }
    })
    
}
var isregister=(req,res)=>{//判断是否已经注册
    usermodel.finduser({username:req.body.username},(data)=>{//在数据库中查找用户输入的用户名
       
       if(data.length>0){//告诉用户 所输入的用户名是否存在
           /*res.cookie('abc',"def")//服务器端向客户端写cookie*/
           res.json({
               ret:true,
               data:false//存在就返回一个false
           })
       }else{
           res.json({
               ret:true,
               data:true//不存在将继续注册
           })
       }
    })
}
var login=(req,res)=>{//登陆
    let{username,password}=req.body;//解构赋值
    const hash =  crypto.createHmac('sha256',password )//第一个参数是固定算法    第二个参数是用户输入的密码
                   .update('I love  cupcakes')
                   .digest('hex');
    usermodel.finduser({username,password:hash},(data)=>{
       if(data.length>0){//如果数据库中匹配到对应的用户名 和密码
           var token =  jwt.sign({username,time:new  Date().getTime()},"haha",{expiresIn:50})//获取用户名 和当前的时间 然后写一个加密字符串  最后设定一个过期时间  防跳
           res.cookie('token',token)//cookie写数据
           res.json({
               ret:true,
               data:true
           })
       }else{
           res.json({
               ret:true,
               data:false
           })
       }
    })
}
var quit=(req,res)=>{//退出功能
    if(req.cookies.token){//如果存在token
       res.cookie("token","")//清空token
        res.json({
           data:{
               logout:true
           }
       })
    }
}
module.exports={
    register,
    login,
    isregister,
    quit
}
 
users.js
 
var express = require('express');
var router = express.Router();
const usercontroller =  require("../controller/usercontroller")
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});
router.post("/register",usercontroller.register)
router.post("/login",usercontroller.login)
router.post("/isregister",usercontroller.isregister)
module.exports=router
 
register.html
 
    <body>
         <input type="text" name="username"  id="username" value="" />
         <input type="text" name="password"  id="password" value="" />
         <button id="reg">注册</button>
         <div id="info"></div>
    </body>
</html>
<script type="text/javascript">
 $("#reg").click(function(){//提交注册请求
       $.post("/users/register",{//用post向数据库传值   这里前面加/users是因为app.js
中的中间件app.use('/users', usersRouter); 规定的写法
           username:$('#username').val(),
           password:$("#password").val()
           
       }).then((res)=>{//数据库返回一个res 如果data为true则可以注册
           if(res.data){
               location.href="login.html"
           }else{
               $("#info").html("注册失败")
           }
       })
    })
    
    $("#username").keyup(function(e){//验证用户名是否存在
       if($(this).val()==="")return;
       $.post("/users/isregister",{//在输入的过程中判断用户名是否存在
           username:$("#username").val()
       }).then((res)=>{
           if(res.data){
               $("#info2").html("√")
           }else{
               $("#info2").html("用户名已存在")
           }
       })
    })
</script>
 
login.html  登录后在list页面显示用户名---sessionStorage
 
<body>
       <input type="text" name="username"  id="username" value="" />
       <input type="text" name="password"  id="password" value="" />
       <button id='login'>登陆</button><p>如果你没有用户名请<a href="register.html">注册</a></p>
       <div id="info">
           
       </div>
    </body>
</html>
<script type="text/javascript">
    $("#login").click(function(){//登录 验证  
       $.post('/users/login',{//向数据库传递用户名和密码
           username:$("#username").val(),
           password:$("#password").val()
       }).then((res)=>{
           if(res.ret){//如果匹配上了 则跳转到list页面
               sessionStorage.setItem("username",$("#username").val())//sessionstorage是本地存储 窗口关闭后本地存储自动清空  setItem()是建立存储内容  存的是用户名(“键”,值)   用于在list等页面显示登录之后的用户名
               location.href="list.html"
           }else{
               $("#info").html('登录失败')
           }
       })
    })
</script>
 
 
smodel.js
 
const mongoose = require("../db/conn")
const smodel =  mongoose.model("second",{name:String},"second")
var getData=(callback)=>{//获取数据     从数据库里拿到所有的数据 回调函数里要有 data  如果有data那么controller中的res接收的时候就需要甩数据
    smodel.find().then((data)=>{
       callback(data)
    })
}
var addData=(name,callback)=>{//添加数据      向数据库中传值  回调函数中没有data
    new  smodel({name:name}).save().then(()=>{
       callback()
    })
}
var delData=(id,callback)=>{//删除数据     在数据库中搜索对应的id 并删除  回调函数中没有data
    smodel.remove({_id:id}).then(()=>{
       callback()
    })
}
var findData=(id,callback)=>{//查找数据  在数据库中查找id对应的数据  回调函数中有data
    smodel.find({_id:id}).then((data)=>{
       callback(data)
    })
}
var modifyData=(id,username,callback)=>{//修改数据    在数据库中修改对应数据  回调函数里没有data
    smodel.update({_id:id},{$set:{name:username}}).then(()=>{
       callback()
    })
}
var queryData=(kw,callback)=>{//模糊查找  在数据库中找到符合要求的数据返给前端  回调函数里有data
    smodel.find({name:new  RegExp(kw)}).then((data)=>{
       callback(data)
    })
}
var pageData=(page,pageSize,callback)=>{//分页   在数据库中将数据分页传递给前端  回调函数中有data
    smodel.find().skip((page-1)*pageSize).limit(Number(pageSize)).then((data)=>{
       callback(data)
    })
}
module.exports={
    getData,
    addData,
    delData,
    findData,
    modifyData,
    queryData,
    pageData
}
 
 
scontroller.js
formidable插件用于上传文件 图片等,使用前需要进行插件安装    cnpm i formidable --save
 
 
const smodel = require("../model/smodel")
var formidable = require('formidable')//引入上传模块
const fs = require("fs")
var  getList=(req,res)=>{
    smodel.getData((data)=>{
       res.json({
           list:data
       })
    })
}
var addList=(req,res)=>{
    smodel.addData(req.params.name,()=>{
       res.json({
           ret:true,
           data:true
       })
    })
}
var delList=(req,res)=>{
    smodel.delData(req.params.id,()=>{
       res.json({
           ret:true,
           data:true
       })
    })
}
var findList = (req,res)=>{
    smodel.findData(req.params.id,(data)=>{
       res.json(data)
    })
}
var modifyList=(req,res)=>{
    smodel.modifyData(req.params.id,req.params.username,()=>{
       res.json({
           ret:true,
           data:true
       })
    })
}
var queryList=(req,res)=>{
    smodel.queryData(req.params.kw,(data)=>{
       res.json(data)
    })
}
var pageList=(req,res)=>{
    smodel.getData((da)=>{
        smodel.pageData(req.params.page,req.params.pageSize,(data)=>{
       res.json({
           list:data,
           count:Math.ceil(da.length/req.params.pageSize)
       })
    })
    })
    
}
var upload=(req,res)=>{//上传  
    var form = new  formidable.IncomingForm();
    form.uploadDir = './public/upload'
     form.parse(req, function(err, fields,  files) {//第一个参数是错误返回 第二个是文档的所有字段 第三参数是上传的文件信息
        if(!files.wj)return//如果没有传文件就返回
          fs.rename(files.wj.path,'./public/upload/'+files.wj.name,()=>{//存储文件的文件夹路径
           console.log('上传成功')
        })
        res.json({
           path:'/upload/'+files.wj.name//返回文件存储的路径
        })
    });
}
module.exports={
    getList,
    addList,
    delList,
    findList,
    modifyList,
    queryList,
    pageList,
    upload
}
 
 
index.js
 
var express = require('express');
var router = express.Router();
const  scontroller=require("../controller/scontroller")
const jwt = require("jsonwebtoken")
 
router.get('/', function(req, res, next) {
  res.redirect('/login.html');   //有‘/’的时候跳转到登陆页面
});
router.use(function(req,res,next){//这是一个中间件  防跳
  
    if(req.url!=='/users/login'&&req.url!=='/users/register'  &&req.url!=='/users/isregister'){  //   登陆,注册,验证用户名是否存在这三个请求是不用token令牌验证的, 之后的增删改查都需要经过令牌验证才可以进行操作或者页面跳转
        jwt.verify(req.cookies.token,'haha',(err)=>{//jwt.verify()是一个验证 方法  用于验证token, 第二个参数要与usercontroller中的login方法中的加密字符串一致  第三个参数是回调函数
           if(!err){//验证通过
               next()
           }else{ //验证token失败
               res.json({
                  msg:"read token fail"
               })
           }
       })
    }else{
       next();//如果是登陆    注册  和验证用户名这三个操作 则可以直接进行下一步操作(页面跳转),不需要token验证
    }
    
})
router.get("/list",scontroller.getList)
router.get("/add/:name",scontroller.addList)
router.get("/del/:id",scontroller.delList)
router.get("/find/:id",scontroller.findList)
router.get("/modifyok/:id/:username",scontroller.modifyList)
router.get("/query/:kw",scontroller.queryList)
router.get("/page/:page/:pageSize",scontroller.pageList)
router.post("/upload",scontroller.upload)
module.exports = router;
 
 
list.html
 
<head>
       <meta charset="UTF-8">
       <title></title>
       <script  src="/javascripts/jquery.js"></script>
           <script  src="/javascripts/baiduTemplate.js"></script>
           <script  src="/javascripts/nav.js"></script>
    </head>
    <body>
       <div id="nav"></div>
       
       <div id="box"></div>
       
       <script type="text/html" id="tem">
       <input type="text" name="txt"  id="txt" value="" />
       <button id="add">添加</button>
           <ul>
           <% for(var i=0; i<  list.length;i++){%>
               <li>
               <%=list[i].name%>
               <button class="del"  data-id="<%=list[i]._id%>">删除</button>
               <button class="btn"  data-id="<%=list[i]._id%>">修改</button>//mongoose数据库中的id变量名为_id
               </li>
           <% } %>
           </ul>
           
           
               <%for(var p=1 ; p<=count ;  p++){%>
               <span class="page"  data-page="<%=p%>" ><%=p%></span>
               
               <% } %>
           
       </script>
    </body>
</html>
<script type="text/javascript">
    
    function pageData(page,pageSize){//分页
        $.get("http://localhost:3000/page/"+page+"/"+pageSize).then((res)=>{//这里的page,pagesize是function传过来的形参   从服务端取值
           if(res.msg){//如果token读取失败 就跳回登录页面
               location.href="login.html"
           }else{//如果读取成功就显示正常的list页面
               nav($("#nav"))
               var  content=baidu.template("tem",{
               list:res.list,
               count:res.count//count是总页数  page是当前页数 pagesize是每一页的信息数
               })
               $("#box").html(content)
           }
           
           })
    }pageData(1,2)
    
    
    $(document).on('click','.page',function(){//点每一页显示不同的内容
        pageData($(this).attr("data-page"),2)
    })
    
  
    $("#box").on('click','#add',function(){//添加
        $.get("http://localhost:3000/add/"+$("#txt").val()).then((res)=>{//向服务端传值
           if(res.ret){
               location.reload()
           }
       })
    })
    $("#box").on('click','.del',function(){//删除
       if(!confirm("确定要删除吗"))return
        $.get("http://localhost:3000/del/"+$(this).attr("data-id")).then((res)=>{
           if(res.ret){
               location.reload()
           }
       })
    })
    
    $(document).on('click','.btn',function(){//修改
       
        $.get("http://localhost:3000/find/"+$(this).attr("data-id")).then((res)=>{
           location.href="modify.html?id="+$(this).attr("data-id")
       })
    })
</script>
 
 
modify.html   修改
 
       <script  src="/javascripts/jquery.js"></script>
           <script  src="/javascripts/baiduTemplate.js"></script>
    </head>
    <body>
       <input type="text" name="txt"  id="username" value="" />
       <input type="text" name="" id="id"  value="" />
       <button id="modifyok">确认修改</button>
    </body>
</html>
<script type="text/javascript">
    var  id=location.search.substring(1).split("=")[1]//问号传参 取值
    console.log(id)
    $.get("http://localhost:3000/find/"+id).then((res)=>{
       $("#username").val(res[0].name)//传回来的res是一个数组,所以用数组的方法取值
       $("#id").val(res[0]._id)
       
    })
    
    $("#modifyok").click(function(){
        $.get("http://localhost:3000/modifyok/"+$("#id").val()+"/"+$("#username").val()).then((res)=>{
           if(res.ret){
                      location.href="/list.html"
                  }
       })
                  
    })
</script>
 
 
query.js  模糊查找
 
    <script  src="/javascripts/baiduTemplate.js"></script>
           <script  src="/javascripts/jquery.js"></script>
           <script  src="/javascripts/nav.js"></script>
    </head>
    <body>
       <div id="nav">
           
       </div>
       <input type="text" name="txt"  id="kw" value="" />
       <button id="btn">查找</button>
       <div id="box">
           
       </div>
       <script type="text/html" id="tem">
           <%for(var i = 0 ; i < list.length  ; i++){%>
               <li><%=list[i].name%></li>
           <% } %>
       </script>
    </body>
</html>
<script type="text/javascript">
    nav($("#nav"))
  $("#btn").click(function(){
    alert(1)
       $.get("http://localhost:3000/query/"+$("#kw").val()).then((res)=>{//通过关键字模糊查找
       var content=baidu.template("tem",{
           list:res
       })
       $("#box").html(content)
    })
  })
 
 
 
upload.js   上传文件
 
<script  src="/javascripts/jquery.js"></script>
           <script  src="/javascripts/baiduTemplate.js"></script>
           <script  src="/javascripts/nav.js"></script>
    </head>
    <body>
       <!--<form action="/upload"  method="post"    enctype="multipart/form-data">
           <input type="file" name="wj"  id="wj" value="" />
           <input type="submit" value="提交"/>
       </form>--> //表单提交的方法
       <div id="nav">
           
       </div>
       <div id="box">
           <input type="file" name="myfile"  id="myfile" value="" />
           <button id="btn">上传</button>
       </div>
       <script type="text/javascript">
           nav($("#nav"))
           $("#btn").click(function(){
               var form = new FormData;
               form.append('wj',myfile.files[0])
               console.log(form)
               $.ajax({
                  type:"POST",
                  url:"/upload",
                  async:true,
                  cache:false,//不适用缓存
                  processData:false,//传输的数据不被jq封装
                  contentType:false,//文件编码不采用jq的形式
                  data:form
               }).then((res)=>{
                  var img = new Image;
                  img.src = res.path;
                   document.body.append(img)//只传图片    如果不写可以传各种文件
               })
           })
       </script>
    </body>
</html>
 
 
nav.js
 
var nav=(node)=>{
    var navcontent=$(`<div>
           <a href="list.html">显示列表</a>||
           <a href="query.html">查询</a>
    </div>`)
    var temSpan = $("<span>").html("你好:"+sessionStorage.getItem("username"))//getItem是取值 
    temSpan.css("width","80px")
    navcontent.append(temSpan)//将取到的值填入进去
    
    var btn= $('<button>退出</button>')
    btn.click(function(){
       $.post("/users/quit").then((res)=>{
           if(res.data.logout){
               alert("谢谢使用")
               location.href='login.html'
           }
       })
    })
    /*var  content=baidu.template(navcontent)*/
    navcontent.append(btn)
    node.html(navcontent)
}
原文地址:https://www.cnblogs.com/zsrTaki/p/11510480.html