nodeNote

get和post请求的区别
  • 作用
    • GET主要用来请求数据,POST 主要用来提交数据
  • 参数的位置
    • GET带参数请求是将参数缀到URL之后 POST将参数放到请求体里面
  • 安全性
    • POST请求相对安全,因为在浏览器中参数会暴露在地址栏
  • GET请求大小有限制,一般为2k,而post请求没有大小限制
模块化

将复杂的程序文件根据一定的规则拆分成多个文件的过程
每一个文件就是一个模块,模块内部数据私有,不过可以暴露给其他数据使用
防止命名冲突 高复用性

express中间件

使用函数封装公共操作,简化代码

  • 全局中间件
  • 路由中间件
app.use(express.static('./public')) //该目录存在一些静态资源
//访问内容经常变化,还是需要设置路由
//如果public目录下有index.html文件,单独也有index.html的路由
//谁写在前面优先执行谁
express框架快速入门
  • 安装
    使用 npm init 命令为您的应用程序创建一个 package.json 文件。
npm init
  • 此命令会提示您输入许多信息,例如应用程序的名称和版本。现在,您只需点击 RETURN 即可接受其中大多数的默认值,但以下情况除外:
entry point: (index.js)
  • 输入 app.js,或任何您想要的主文件名称。如果您希望它是 index.js,请按 RETURN 以接受建议的默认文件名。
  • ejs的安装(或者)
npm install ejs --save-d
  • 最后安装依赖
npm install express
Express 生成器
  • 对于较早的 Node 版本,将应用程序生成器安装为全局 npm 包,然后启动它:

    npm install -g express-generator
    
  • 添加ejs的模板引擎的支持

    express -e -15generator
    
lowdb
npm install lowdb@1.0.0
// 导入lowdb
const low = require('lowdb')
const FileSync = require('lowdb/adapters/FileSync')
const adapter = new FileSync('db.json')
// 获取db对象
const db = low(adapter)
// 初始化数据
 db.defaults({ posts: [], user: {} }).write()
 // 写入数据
 db.get('posts').unshift({id:666,title:"其实还挺简单的"}).write()
// // 获取数据
 console.log(db.get('posts').value());
// 获取单条数据
 let res = db.get('posts').find({id:666}).value()
 console.log(res);
// 更新数据
 let res = db.get('posts').find({id:666}).assign({title:'其实还挺难的'}).write()
 console.log(res);
// 移除数据
 let res = db.get('posts').remove({id:1}).write()
 console.log(res);
shortid
npm install shortid
const shortid = require('shortid')
let id = generate()
文件上传
  • 比body-parse功能更加强大
const formidable = require('formidable')
// 创建form表单对象
  const form = new formidable.IncomingForm({
    // 设置上传文件的保存目录
    uploadDir:__dirname+'/../public/images',
    // 保持文件后缀
    keepExtensions:true
  });
  // 解析请求报文
  form.parse(req, (err, fields, files) => {
    if (err) {
      next(err);
      return;
    }
    console.log(fields);
    console.log(files);
    // res.json({ fields, files });
    let url = '/images/'+ files.portrait[0].newFilename //将来保存在数据库中
    res.send(url)
mongodb数据库
//避免promise处理文件操作
//npm install mongoose@4.13.0
// 导入mongoose
const mongoose = require('mongoose')

// 连接mongodb服务
mongoose.connect('mongodb://127.0.0.1:27017/demon')

// 设置回调
mongoose.connection.once('open',()=>{
    console.log("连接成功");
    // 创建文档的结构对象
    // 设置集合中 文档的属性以及属性值的类型
    let BookSchema = new mongoose.Schema({
        name:String,
        author:String,
        price:Number
    })
    // 创建模型对象 对文档操作的封装对象 books:需要操作的集合名称 BookSchema:结构对象
    let BookModel = mongoose.model('books',BookSchema);
    // 新增
    BookModel.create({
        name:'西游记',
        author:'吴承恩',
        price:19.9
    },(err,data)=>{
        // 判断是否有错误
        if(err){
            console.log(err);
            return
        }
        // 如果没有出错,则输出插入后的文本对象
        console.log(data);
        // 关闭数据库连接
        mongoose.disconnect()
    })
})
mongoose.connection.on('error',()=>{
    console.log("连接失败");
})
mongoose.connection.on('close',()=>{
    console.log("连接关闭");
})
 关闭mongodb的连接服务
 setTimeout(()=>{
    mongoose.disconnect();
 },2000)
//最新版的mongoose,使用Promise来处理插入文档的操作
BookModel.create({
    name: '西游记',
    author: '吴承恩',
    price: 19.9
})
.then(data => {
    console.log(data);
})
.catch(err => {
    console.error(err);
});

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

字段校验

Mongoose有一些内建验证器,可以对字段进行验证

  • 必选项 required
  • 默认值 default
  • 枚举值 enum
  • 唯一值 unique ( unique 需要重建集合才能有效果 永远不要相信用户的输入)
文档操作
  • 删除

    • 一条deleteOne({},(err,data)=>{})
    • 多条deleteMany({},(err,data)=>{})
  • 更新

    • 一条updateone({},{}(err,data)=>{})
    • 多条updateMany({},{}(err,data)=>{})
  • 读取

    • 一条findOne({},(err,data)=>{})
    • 一条findById({},(err,data)=>{})
    • 多条find({},(err,data)=>{})
条件控制
  • 运算符 在mongodb不能 > < >= <= !== 等运算符,需要使用替代符号

    • > 使用 $gt
    • < 使用 $lt
    • >= 使用 $gte
    • <= 使用 $lte
    • !== 使用 $ne
  • 逻辑运算

  • $or 逻辑或的情况

    db.students.find({$or:[{age:18},{age:24}]});
    
  • $and 逻辑与的情况

```js
db.students.find({$and: [{age: {$lt:20}}, {age: {$gt: 15}}]})
```
  • 正则匹配 条件中可以直接使用 JS 的正则语法,通过正则可以进行模糊查询

    db.students.find({name:/imissyou/})
    db.students.find({name:new RegExp('imissyou')})
    
个性化读取
  • 字段筛选

    //0:不要的字段
    //1:要的字段
    SongModel.find().select({_id:0,title:1}).exec(function(err,data){
     if(err) throw err;
     console.log(data);
     mongoose.connection.close();
     })
    
  • 数据排序

//sort 排序
//1:升序
//-1:倒序
SongModel.find().sort({hot:1}).exec(function(err,data){
 if(err) throw err;
 console.log(data);
 mongoose.connection.close();
 });
  • 数据截取

    //skip 跳过   limit 限定
    SongModel.find().skip(10).limit(10).exec(function(err,data){
     if(err) throw err;
     console.log(data);
     mongoose.connection.close();
     });
    
json-server

本身是一个js编写的工具包,可以快速搭建restfulApi服务

//全局安装
npm i -g json-serverd
//文件启动
json-server --watch db.json
API接口
var express = require('express');
var router = express.Router();

const shortid = require('shortid')
// 导入moment
const moment = require('moment')
const AccountModel = require('../../models/AccountModel')
// console.log(moment('2023-02-24').toDate());
/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

// 记账本的列表
router.get('/account', function(req, res, next) {
  
AccountModel.find().sort({time:-1}).exec((err,data)=>{
    if(err){
      res.json({
        code:'1001',
        msg:'读取失败~~',
        data:null
      })
    }
    res.json({
        // 响应编号
        code: '0000',
        // 响应信息
        msg: '读取成功',
        // 响应的数据
        data: data
    })
  })

});
// 新增记录
router.post('/account',(req,res)=>{
  // let id = shortid.generate();
  // // 获取请求体的数据
  // console.log(req.body);
  // // 写入文件
  // db.get('accounts').unshift({id:id, ...req.body}).write()
   AccountModel.create({
    ...req.body,
    time:moment(req.body.time).toDate()
   },(err,data)=>{
    if(err){
      res.json({
        code:'1002',
        msg:'创建失败~~~',
        data:null
      })
    }
    res.json({
        code:'0000',
        msg:'创建成功',
        data:data
    })
   })
})
// 删除记录
router.delete('/account/:id',(req,res)=>{
  let id = req.params.id
  AccountModel.deleteOne({_id: id},(err,data)=>{
    if (err) {
      res.json({
        code:'1003',
        msg:'删除账单失败',
        data:null
      })
      return
    }
    res.json({
        code:'0000',
        msg:'删除成功',
        data:data
    })
  })
 
})
// 获取单个信息
router.get('/account/:id',(req,res)=>{
    // 获取id参数
    let {id} = req.params
    // 查询数据库
    AccountModel.findById(id,(err,data) =>{
        if(err){
           return res.json({
                code:'1004',
                msg:'查询错误',
                data:null
            })
        }
        res.json({
            code:'0000',
            msg:'获取成功',
            data:data
        })
    })
})
//更新单个账号信息
router.patch('/account/:id',(req,res)=>{
    let { id } = req.params
    AccountModel.updateOne({ _id: id},req.body,(err,data)=>{
        if(err){
            return res.json({
                 code:'1005',
                 msg:'更新错误',
                 data:null
             })
         }
         AccountModel.findById(id,(err,data)=>{
            if(err){
                return res.json({
                    code:'1004',
                    msg:'读取错误',
                    data:null
                })
            }
         res.json({
             code:'0000',
             msg:'更新成功',
             data:data
         })
        })
    })
})
module.exports = router;

cookie会话控制
npm install cookie-parser
session会话控制
const express = require('express');
 //1. 安装包   npm i express-session  connect-mongo
 //2. 引入 express-session  connect-mongo
 const session = require("express-session");
 const MongoStore = require('connect-mongo');
 const app = express();
 //3. 设置 session 的中间件
app.use(session({
 name: 'sid',   //设置cookie的name,默认值是:connect.sid
 secret: 'atguigu', //参与加密的字符串(又称签名)
saveUninitialized: false, //是否为每次请求都设置一个cookie用来存储session的id
 resave: true,  //是否在每次请求时重新保存session
 store: MongoStore.create({
 mongoUrl: 'mongodb://127.0.0.1:27017/project' //数据库的连接配置
}),
 cookie: {
 httpOnly: true, // 开启后前端无法通过 JS 操作
maxAge: 1000 * 300 // 这一条 是控制 sessionID 的过期时间的!!!3min后过期
},
 }))
 //创建 session
 app.get('/login', (req, res) => {
 //设置session
 req.session.username = 'zhangsan';
 req.session.email = 'zhangsan@qq.com'
 res.send('登录成功');
 })
 //获取 session
 app.get('/home', (req, res) => {
 console.log('session的信息');
 console.log(req.session.username);
 if (req.session.username) {
 res.send(`你好 ${req.session.username}`);
 }else{
 res.send('登录  注册');
 }
 })
 //销毁 session
 app.get('/logout', (req, res) => {
 //销毁session
 // res.send('设置session');
 req.session.destroy(() => {
 res.send('成功退出');
 });
 });
 app.listen(3000, () => {
 console.log('服务已经启动, 端口 ' + 3000 + ' 监听中...');
})
session和cookie的区别
  • 存在的位置

    • cookie 浏览器
    • session 服务器
  • 安全性

    • cookie是以明文的方式存放在客户端,安全性相对较低
    • session存放在服务器端安全性相对较好
  • 网络传输量

    • cookie设置内容过多会增大报文体积,会影响传输效率
    • session存放在服务器,只是通过cookie传递id,不会影响传输效率
  • 存储限制

    • 浏览器限制单个cookie保存的数据不能超过4k且单个域名下的存储数量也有限制

    • session数据存储在服务器中,没有限制

加密算法包md5

单向不可逆加密,通过原数据找到加密数据,不能通过加密数据找到原数据,更好的保护用户的密码

//npm i md5
const md5 = require('md5')
UserModel.create({...req.body,password:md5(req.body.password)},(err,data)=>{
        if(err){
            res.status(500).send('注册失败,请稍后再试')
            return
        }
        res.render('success',{msg:'注册成功',url: '/login'})
    })
token会话控制
  • token是服务端生成并且返回给http客户端的一串加密字符串,token中保存着用户信息
  • token的作用是实现会话控制可以识别用户的身份主要用于移动端的app
  • token的工作流程 填写账号和密码验证身份 验证通过后响应token token一般是响应体返回客户端的
  • token的特点
    • 服务器的压力更低
      • 数据存在客户端
    • 相对安全
      • 数据加密
      • 可以避免csrf(跨站请求的伪造)
    • 扩展性更强
      • 服务间可以共享
      • 增加服务节点更简单
// // 导入jwt
const jwt = require('jsonwebtoken')

// 创建token
// let token = jwt.sign(用户数据,加密字符串,配置对象);
let token = jwt.sign({
    username:'张三'
},'atguigu',{
    expiresIn:60,//单位是秒
})
console.log(token);
let t = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IuW8oOS4iSIsImlhdCI6MTY5OTc2NDA1NSwiZXhwIjoxNjk5NzY0MTE1fQ.fCeTyBIZPPEMIvuKw2nKq5IHQISo6_l5aPLb9Rp5bXw'
// 校验token
jwt.verify(t,'atguigu',(err,data)=>{
    if(err){
        console.log('校验失败');
        return
    }
    console.log(data);
})
  • 扩展性更强
    • 服务间可以共享
    • 增加服务节点更简单
// // 导入jwt
const jwt = require('jsonwebtoken')

// 创建token
// let token = jwt.sign(用户数据,加密字符串,配置对象);
let token = jwt.sign({
    username:'张三'
},'atguigu',{
    expiresIn:60,//单位是秒
})
console.log(token);
let t = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IuW8oOS4iSIsImlhdCI6MTY5OTc2NDA1NSwiZXhwIjoxNjk5NzY0MTE1fQ.fCeTyBIZPPEMIvuKw2nKq5IHQISo6_l5aPLb9Rp5bXw'
// 校验token
jwt.verify(t,'atguigu',(err,data)=>{
    if(err){
        console.log('校验失败');
        return
    }
    console.log(data);
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dayDAYup&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值