• mongodb导入数据,保创建新项目


    1、回顾

    2、导入数据

    2.1 excel数据表格

    2.2 设计导入数据的路由 routes/users.js

    router.get('/upload', function (req, res, next) {
      res.send('上传数据')
    })
    

    2.3 安装 导入数据的模块

    cnpm i node-xlsx -S

    2.4 实现数据导入 ---- 读取文件信息

    var xlsx = require('node-xlsx'); // 数据导入模块
    // 导入的文件的绝对路径
    var xlsxfile = "E:/course-wxx/sh1908/lesson3/code/week1-node/day03/myapp/1902.xlsx"
    
    router.get('/upload', function (req, res, next) {
      // 1.读取文件的信息并且打印
      res.send(xlsx.parse(xlsxfile))
    })
    

    2.5 实现数据导入 ---- 解析需要的数据 ---- 拿到数据

    router.get('/upload', function (req, res, next) {
      // 1.读取文件的信息并且打印
      // res.send(xlsx.parse(xlsxfile)) // [{}, {}]
    
      // 2、取数组中的第一个作为第一张表的数据
      var obj = xlsx.parse(xlsxfile)[0]
      // res.send(obj) // {name:'',data:[[],[]]}
      res.send(obj.data) // [[], [], []] 内层数组就是Excel表格的每一行的数据
    })
    

    2.6 实现数据导入 ---- 解析需要的数据

    router.get('/upload', function (req, res, next) {
      // 1.读取文件的信息并且打印
      // res.send(xlsx.parse(xlsxfile)) // [{}, {}]
    
      // 2、取数组中的第一个作为第一张表的数据
      var obj = xlsx.parse(xlsxfile)[0]
      // res.send(obj) // {name:'',data:[[],[]]}
      // res.send(obj.data) // [[], [], []] 内层数组就是Excel表格的每一行的数据
    
      // 3、获取数组的长度,循环遍历数据,组成需要的对象
      var len = obj.data.length
      // 第一条数据是标题  ["姓名","性别","年龄","公司","密码","阶段","籍贯"],下标从1开始
      // 设计一个插入的数据
      var insertData = []
      for (var i = 1; i < len; i++) {
        insertData.push({
          userid: 'user_' + uuid.v1(),
          username: obj.data[i][0], // ["张玉印",1,18,"千锋",217,3,"安徽"]
          sex: obj.data[i][1] * 1,
          age: obj.data[i][2] * 1,
          company: obj.data[i][3],
          password: obj.data[i][4] + '',
          lesson: obj.data[i][5] * 1,
          city: obj.data[i][6]
        })
      }
    
    })
    
    

    2.7 实现数据导入 ---- 插入数据库

    router.get('/upload', function (req, res, next) {
      // 1.读取文件的信息并且打印
      // res.send(xlsx.parse(xlsxfile)) // [{}, {}]
    
      // 2、取数组中的第一个作为第一张表的数据
      var obj = xlsx.parse(xlsxfile)[0]
      // res.send(obj) // {name:'',data:[[],[]]}
      // res.send(obj.data) // [[], [], []] 内层数组就是Excel表格的每一行的数据
    
      // 3、获取数组的长度,循环遍历数据,组成需要的对象
      var len = obj.data.length
      // 第一条数据是标题  ["姓名","性别","年龄","公司","密码","阶段","籍贯"],下标从1开始
      // 设计一个插入的数据
      var insertData = []
      for (var i = 1; i < len; i++) {
        insertData.push({
          userid: 'user_' + uuid.v1(),
          username: obj.data[i][0], // ["张玉印",1,18,"千锋",217,3,"安徽"]
          sex: obj.data[i][1] * 1,
          age: obj.data[i][2] * 1,
          company: obj.data[i][3],
          password: obj.data[i][4] + '',
          lesson: obj.data[i][5] * 1,
          city: obj.data[i][6]
        })
      }
      // 插入数据,返回列表
      sql.insert(User, insertData).then(() => {
        res.redirect('/users')
      })
    
    })
    

    2.7 实现数据导入 ---- 前端添加导入的按钮

    <a href="/users/upload">
      <button class="btn btn-default">导入数据</button>
    </a>
    

    3、登陆功能

    3.1 准备登陆页面 login.ejs ---- 复制 pages/examples/login.html 代码

    3.2 添加跳转到 登陆的 路由 routes/index.js

    router.get('/login', function(req, res, next) {
      res.render('login');
    });
    

    3.3 设计 管理员集合 sql/collection/admins.js

    const mongoose = require('./../db.js'); // 引入数据库连接模块
    const Schema = mongoose.Schema; // 拿到当前数据库相应的集合对象
    
    // 设计用户表的集合
    const adminSchema = new Schema({
      adminid: {type: String },
      adminname: { type: String },
      password: { type: String },
      roles: { type: Number } // 管理员的权限
    })
    
    module.exports = mongoose.model('Admin', adminSchema);
    

    3.4 密码加密 ---- 插入数据库

    md5加密 ---- 安全性 低 ---- 一般不推荐使用,但是你必须得知道

    // cnpm i md5 -S
    var str = 123456
    md5(str)
    

    bcrypt 加密

    // cnpm i bcryptjs -S
    const bcrypt = require('bcryptjs'); 
    // 设置密码强度 
    var salt = bcrypt.genSaltSync(10); 
    // HASH值 为加密的密码 
    var hash = bcrypt.hashSync('123456',salt); 
    console.log(hash) 
    // 获取值 和 密码对比
     console.log(bcrypt.compareSync('123456', hash))
    

    myapp/bcrypt.js ---- 每次加密后都不一致 ---- 确保了加密的安全性

    var bcrypt = require('bcryptjs')
    
    var salt = bcrypt.genSaltSync(10); 
    
    var hash = bcrypt.hashSync('123456', salt)
    
    console.log(hash)
    // $2a$10$88h5h1QDyHQKTr9Q/9uMIuzK0pThnDFreORqSBkwrtCVz1VPuclsS
    // $2a$10$j3W.M9OYuV2Wruk42x4dkOA5cCPNj.MfXpsuAWo5AFeaIcK9t0Cau
    // $2a$10$Z1s1CM3mY0Lcz9WdjQuQXO2363un7qXoGeoiq4A5fBZdRWhTN2Jii
    

    ** 给管理员集合插入一条数据 myapp/insertAdmin.js **

    var Admin = require('./sql/collection/admins')
    var sql = require('./sql')
    var uuid = require('node-uuid')
    sql.insert(Admin, [{
      adminid: 'admin_' + uuid.v1(),
      adminname: 'wudaxun',
      password: '$2a$10$j3W.M9OYuV2Wruk42x4dkOA5cCPNj.MfXpsuAWo5AFeaIcK9t0Cau',
      roles: 1
    },
    {
      adminid: 'admin_' + uuid.v1(),
      adminname: 'admin',
      password: '$2a$10$j3W.M9OYuV2Wruk42x4dkOA5cCPNj.MfXpsuAWo5AFeaIcK9t0Cau',
      roles: 2
    }]).then(() => {
      console.log('插入成功')
    })
    

    3.5 添加登陆功能的 action路由 routes/index.js

    router.post('/loginAction', function(req, res, next) {
      var { adminname, password } = req.body
      sql.find(Admin, { adminname: adminname }).then((data) => {
        if (data.length === 0) {
          console.log('不是管理员账户')
        } else {
          var pwd = data[0].password // 数据中的加密后的密码
          var flag = bcrypt.compareSync(password, pwd) // 如果为真,表示正确
          if (flag) {
            res.redirect('/')
          } else {
            res.redirect('/login')
          }
        }
      })
    });
    

    login.ejs 添加表单的action值

    <form action="/loginAction" method="post"></form>
    

    4、除了登陆的路由外,其余的页面都需要登陆才可以访问

    app.js

    // 设置所有的路由
    app.all('*', function (req, res, next) {
      next()
    })
    

    4.1 如何判断用户是登陆的状态

    cookie
    可以直接使用 (cookie 可以在客户端和服务端设置和读取)

    服务端设置cookie res.cookie('isLogin', 'ok') ---- 登陆成功时设置 --- index.js

    if (flag) {
      res.cookie('isLogin', 'ok')
      res.redirect('/')
    } else {
      res.redirect('/login')
    }
    

    服务端读取cookie req.cookies.isLogin ---- app.js

    // 设置所有的路由
    app.all('*', function (req, res, next) {
      console.log(req.url)
      // 如果是登陆 和 登陆的请求,需要过滤掉
      if (req.url === '/login' || req.url === '/loginAction') {
        next() // 继续执行
      } else {
        if (req.cookies.isLogin === 'ok') {
          next()
        } else {
          console.log('未登录')
          res.redirect('/login')
        }
      }
    })
    

    退出 header.ejs

    <a href="/logout" class="btn btn-default btn-flat">Sign out</a>
    

    routes/index.js处设计一个退出的路由

    router.get('/logout', function(req, res, next) {
      res.cookie('isLogin', 1)
      res.redirect('/login')
    });
    

    session

    cnpm i express-session -S

    app.js 配置

    var session = require('express-session');
    
    app.use(session({ 
      secret : "nihao", //加密session,随便写 
      cookie : {maxAge : 60*1000*30}, //设置过期时间 --- 半小时 
      resave : true, //强制保存session 默认为 true,建议设置成false 
      saveUninitialized : false ////强制将未初始化的session存储 默认为true,建议设置成true 
    }));
    

    登陆成功设置 session req.session.isLogin = 'ok'

    if (flag) {
      req.session.isLogin = 'ok'
      res.redirect('/')
    } else {
      res.redirect('/login')
    }
    

    所有的路由需要判断登陆状态 app.js

    app.all('*', function (req, res, next) {
      if (req.url === '/login' || req.url === '/loginAction') {
        next()
      } else {
        if (req.session.isLogin === 'ok') {  // 读取
          next()
        } else {
          res.redirect('/login')
        }
      }
    })
    

    退出

    router.get('/logout', function(req, res, next) {
      req.session.isLogin = 1
      res.redirect('/login')
    });
    

    5、restful api接口的规范

    6、postman测试接口

    7、自定义接口

    express myapp --view=ejs
    cd myapp
    cnpm i
    cnpm i mongoose@4 -S
    配置dev指令
    cnpm run dev

    复制 sql文件夹至本项目

    复制routes/users.js 至本项目, 只保留获取的数据,将 res.render() 替换成为 res.send()即可

    router.get('/', function(req, res, next) {
      sql.find(User, {}, {_id: 0}).then(data => {
        /***
          res.render('users', {
            activeIndex: 1,
            list: data
          })
        */
        res.send({
          code: '200',
          message: 'success',
          data: data
        })
      })
    });
    

    8、用户列表的分页功能接口

    继续封装sql/index.js,添加分页的模块

    paging (CollectionName, whereObj, showObj, limitNum, pageCode) {
      return new Promise((resolve, reject) => {
        // limit(limitNum) 每页显示个数
        // skip(limitNum * pageCode) // 每页从哪一个开始
        CollectionName.find(whereObj, showObj).limit(limitNum).skip(limitNum * pageCode).exec((err, data) => {
          if (err) throw err;
          resolve(data)
        })
      })
    }
    

    routes/users.js 中获取用户信息接口 添加参数

    router.get('/', function(req, res, next) {
      let { limitNum, pageCode } = req.query; // 获取用户提交的分页数据
      limitNum = limitNum * 1 || 10
      pageCode = pageCode * 1 || 0
      sql.paging(User, {}, {_id: 0}, limitNum, pageCode).then(data => {
        res.send({
          code: '200',
          message: 'success',
          data: data
        })
      })
    });
    

    postman 测试接口

    编写接口文档 /api/用户接口.md

    9、 前端请求数据

    $.ajax({
      url: 'http://localhost:3000/users',
      success: function (data) {
        console.log(data)
      }
    })
    

    遇到如下问题 ----- 本请求 跨域了

    Access to XMLHttpRequest at 'http://localhost:3000/users' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
    

    10、解决跨域问题

    10.1 jsonp解决跨域问题 (不推荐使用 --- 既麻烦前端 又麻烦后端)

    routes/users.js

    // jsonp解决跨域问题
    router.get('/', function(req, res, next) {
      let _callback = req.query.callback
      let { limitNum, pageCode } = req.query; // 获取用户提交的分页数据
      limitNum = limitNum * 1 || 10
      pageCode = pageCode * 1 ||0
      sql.paging(User, {}, {_id: 0}, limitNum, pageCode).then(data => {
        var obj = {
          code: '200',
          message: 'success',
          data: data
        }
        if (_callback) {
          // 这两步设置发送也是NODE.JS发送JSONP必备 
          res.type('text/javascript'); 
          res.send(_callback + '(' + JSON.stringify(obj) + ')');
        } else {
          res.json(obj)
        }
      })
    });
    

    请求数据

    $.ajax({
      url: 'http://localhost:3000/users',
      dataType: 'jsonp',  // ******************************
      success: function (data) {
        console.log(data)
      }
    })
    

    10.2 cors解决跨域问题 (推荐使用,前端正常使用,后端麻烦)

    app.js中添加如下代码

    var allowCrossDomain = function (req, res, next) { 
      res.header('Access-Control-Allow-Origin', '*');//自定义中间件,设置跨域需要的响应头。 
      next(); 
    }; 
    app.use(allowCrossDomain) ////运用跨域的中间件
    

    接口无需做额外的配置

    
    // cors 解决跨域的问题,不需要修改此接口
    router.get('/', function(req, res, next) {
      let { limitNum, pageCode } = req.query; // 获取用户提交的分页数据
      limitNum = limitNum * 1 || 10
      pageCode = pageCode * 1 ||0
      sql.paging(User, {}, {_id: 0}, limitNum, pageCode).then(data => {
        res.send({
          code: '200',
          message: 'success',
          data: data
        })
      })
    });
    

    请求数据

    $.ajax({
      url: 'http://localhost:3000/users',
      success: function (data) {
        console.log(data)
      }
    })
    

    10.3 反向代理 ---- vue/react

    客户端访问服务器会遇到跨域问题,但是服务器与服务器之前不存在跨域问题

    自己请求自己的服务器,自己的服务器去请求别人的服务器

    拓展:正向代理与反向代理:https://blog.csdn.net/fengpojian/article/details/79259799

    正向代理: A找C借钱,借不到,A找B,B找C借钱,C把钱给了B,B把钱给了A,但是C不知道是A借的钱,此时B就是代理 ----- 正向代理

    反向代理: 学员来千锋学习H5,H5有很多的老师,你不知道哪一个老师教你,但是你来了就一定会有老师教你
    双11买东西,阿里有成千上万台服务器,你不知道你访问的是那一台服务器,但是你知道访问 https://www.taobao.com 就可以访问淘宝了,此时 https://www.taobao.com 就是一个代理 ---- 反向代理
    正向代理」代理的对象是客户端,「反向代理」代理的对象是服务端

  • 相关阅读:
    协议详解1——概要
    协议学习之 vamei博客系列 总结
    DDOS介绍
    python基础教程总结15——7 自定义电子公告板
    python基础教程总结15——6 CGI远程编辑
    python基础教程总结15——5 虚拟茶话会
    python基础教程总结15——4 新闻聚合
    python基础教程总结15——3 XML构建网址
    如何在远程桌面的服务器上访问本地磁盘
    C# 如何把dataTable以参数的形式传入 sql 存储过程
  • 原文地址:https://www.cnblogs.com/hy96/p/11703418.html
Copyright © 2020-2023  润新知