Node.js基础(二)

1. NodeJs操作Mongodb

1.1. 连接数据库

javascript 复制代码
const mongoose = require("mongoose")
mongoose.connect("mongodb://127.0.0.1:27017/company-system")

1.2. 创建模型

javascript 复制代码
const mongoose = require("mongoose")
const Schema = mongoose.Schema

const UserType = {
    username:String,
    password:String,
    gender:Number,
    introduction:String,
    avatar:String,
    role:Number
}
const UserModel = mongoose.model("user",new Schema(UserType))
module.exports  = UserModel 

1.3. 增加数据

javascript 复制代码
UserModel.create({
    introduction,username,gender,avatar,password,role
})

1.4. 查询数据

javascript 复制代码
UserModel.find({username:"wyb"},["username","role","introduction","password"]).sort({createTime:-1}).skip(10).limit(10)

1.5. 更新数据

javascript 复制代码
UserModel.updateOne({ _id },{ introduction,username,gender,avatar })

1.6. 删除数据

javascript 复制代码
UserModel.deleteOne({_id})

2. 登录鉴权

javascript 复制代码
const express = require("express");
const session = require("express-session");
const MongoStore = require("connect-mongo");
const app = express();

app.use(
  session({
    secret: "this is session", // 服务器生成 session 的签名
    resave: true, 
    saveUninitialized: true, // 强制将为初始化的 session 存储
    cookie: {
      maxAge: 1000 * 60 * 10,// 过期时间
      secure: false, // true:只有 https 协议才能访问cookie
    },
    rolling: true, // true:超时前刷新,cookie 会重新计时;false:在超时前刷新多少次,都是按照第一次刷新开始计时。
    store: MongoStore.create({
      mongoUrl: 'mongodb://127.0.0.1:27017/kerwin_session',
      ttl: 1000 * 60 * 10 // 过期时间
  	}),
  })
);

app.use((req,res,next)=>{
  if(req.url==="/login"){
    next()
    return;
  }
  if(req.session.user){
      req.session.garbage = Date();
      next();
  } else{
   	  res.redirect("/login")   
  }
})

2.2. JSON Web Token (JWT)

  • 代码实现
javascript 复制代码
//jsonwebtoken 封装
const jsonwebtoken = require("jsonwebtoken")
const secret = "wyb- secret"
const JWT = {
    generate(value, exprires){
        return jsonwebtoken.sign(value, secret, {expiresIn: exprires})
    },
    verify(token){
        try {
            return jsonwebtoken.verify(token, secret)
        } catch(e) {
            return false
        }
    }
}
module.exports = JWT
javascript 复制代码
//node中间件校验
app.use((req,res,next)=>{
  // 如果token有效 ,next() 
  // 如果token过期了, 返回401错误
  if(req.url==="/login"){
    next()
    return;
  }

  const token = req.headers["authorization"].split(" ")[1]
  if(token) {
    const payload = JWT.verify(token)
    if(payload) {
      const newToken = JWT.generate({
        _id: payload._id,
        username: payload.username
      }, "1d")
      res.header("Authorization", newToken)
      next()
    } else {
      res.status(401).send({errCode: "-1", errorInfo: "token过期"})
    }
  }
})
javascript 复制代码
// 生成token
const token = JWT.generate({
    _id: result[0]._id,
    username: result[0].username
}, "1d")
res.header("Authorization", token)

3. 文件上传管理

Multer 是一个 node.js 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件。

  • 前端
javascript 复制代码
const params = new FormData()
params.append('wybfile', file.file)
params.append('username', this.username)
const config = {
	headers: {
		"Content-Type":"multipart/form-data"
	}
}
http.post('/api/upload', params, config).then(res => {
	this.imgpath = 'http://localhost:3000' + res.data
})	

Multer 会添加一个 body 对象 以及 filefiles 对象 到 express 的 request 对象中。 body 对象包含表单的文本域信息,filefiles 对象包含对象表单上传的文件信息。

  • 后端
javascript 复制代码
router.post('/upload', upload.single('wybfile'),function(req, res, next) {
	console.log(req.file)
})

4. 操作MySQL

javascript 复制代码
const express = require('express')
const app = express()
const mysql2 = require('mysql2')
const port = 9000

app.get('/', async (req, res) => {
  const config = getDBConfig()
  const promisePool = mysql2.createPool(config).promise();
  let user = await promisePool.query('select * from students');
      if (user[0].length) {
          // 存在用户
          res.send(user[0])
      } else {
          // 不存在
          res.send( {
              code: -2,
              msg: 'user not exsit',
          })
      }      
})
app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

function getDBConfig() {
  return {
    host: '127.0.0.1',
    user: 'root',
    port: 3306,
    password: '',
    database: 'wyb_test',
    connectionLimit: 1 // 创建一个连接池
  }
}
javascript 复制代码
查询:promisePool.query('select * from users');
插入:promisePool.query('INSERT INTO `users`(`id`,`name`,`age`, `password`) VALUES (?,?,?,?)',[null,"kerwin",100,"123456"]);
更新:promisePool.query(`UPDATE users SET name = ? ,age=? WHERE id = ?`,["xiaoming2",20,1])
删除:promisePool.query(`delete from users where id=?`,[1])

5. Socket编程

5.1. ws模块

  • 服务端
javascript 复制代码
const  WebSocket = require("ws")
WebSocketServer = WebSocket.WebSocketServer
const wss = new WebSocketServer({ port: 8080 });

wss.on('connection', function connection(ws) {
    ws.on('message', function message(data, isBinary) {
        wss.clients.forEach(function each(client) {
            if (client !== ws && client.readyState === WebSocket.OPEN) {
                client.send(data, { binary: isBinary });
            }
        });

    });
    ws.send('欢迎加入聊天室');
});
  • 客户端
javascript 复制代码
let ws = new WebSocket("ws://localhost:8080")
ws.onopen = ()=>{
    console.log("open")
}
ws.onmessage = (evt)=>{
    console.log(evt.data)
}

5.2. 授权验证

javascript 复制代码
// 前端
var ws = new WebSocket(`ws://localhost:8080?token=${localStorage.getItem("token")}`)
ws.onopen = () => {
     ws.send(JSON.stringify({
        type: WebSocketType.GroupList
     }))
}
ws.onmessage = (evt) => {
    console.log(evt.data)
}
// 后端
const WebSocket = require("ws");
const JWT = require('../util/JWT');
WebSocketServer = WebSocket.WebSocketServer
const wss = new WebSocketServer({ port: 8080 });

wss.on('connection', function connection(ws, req) {
  const myURL = new URL(req.url, 'http://127.0.0.1:3000');
  const payload = JWT.verify(myURL.searchParams.get("token"))
  if (payload) {
    ws.user = payload
    ws.send(createMessage(WebSocketType.GroupChat, ws.user, "欢迎来到聊天室"))
    sendBroadList() //发送好友列表
  } else {
    ws.send(createMessage(WebSocketType.Error, null, "token过期"))
  }
  ws.on('message', function message(data, isBinary) {
    const messageObj = JSON.parse(data)
    switch (messageObj.type) {
      case WebSocketType.GroupList:
        ws.send(createMessage(WebSocketType.GroupList, ws.user, JSON.stringify(Array.from(wss.clients).map(item => item.user))))
        break;
      case WebSocketType.GroupChat:
        wss.clients.forEach(function each(client) {
          if (client !== ws && client.readyState === WebSocket.OPEN) {
            client.send(createMessage(WebSocketType.GroupChat, ws.user, messageObj.data));
          }
        });
        break;
      case WebSocketType.SingleChat:
        wss.clients.forEach(function each(client) {
          if (client.user.username === messageObj.to && client.readyState === WebSocket.OPEN) {
            client.send(createMessage(WebSocketType.SingleChat, ws.user, messageObj.data));
          }
        });
        break;
    }

    ws.on("close",function(){
      // 删除当前用户
      wss.clients.delete(ws.user)
      sendBroadList() //发送好用列表
    })
  });
});
const WebSocketType = {
  Error: 0, //错误
  GroupList: 1,//群列表
  GroupChat: 2,//群聊
  SingleChat: 3//私聊
}
function createMessage(type, user, data) {
  return JSON.stringify({
    type: type,
    user: user,
    data: data
  });
}

function sendBroadList(){
  wss.clients.forEach(function each(client) {
    if (client.readyState === WebSocket.OPEN) {
      client.send(createMessage(WebSocketType.GroupList, client.user, JSON.stringify(Array.from(wss.clients).map(item => item.user))))
    }
  });
}

5.3. socket.io模块

  • 服务端
javascript 复制代码
const io = require('socket.io')(server);
io.on('connection', (socket) => {
  const payload = JWT.verify(socket.handshake.query.token)
  if (payload) {
    socket.user = payload
    socket.emit(WebSocketType.GroupChat, createMessage(socket.user, "欢迎来到聊天室"))
    sendBroadList() // 发送好友列表
  } else {
    socket.emit(WebSocketType.Error, createMessage(null, "token过期"))
  }
  socket.on(WebSocketType.GroupList, () => {
    socket.emit(WebSocketType.GroupList, createMessage(null, Array.from(io.sockets.sockets).map(item => item[1].user).filter(item=>item)));
  })
  socket.on(WebSocketType.GroupChat, (messageObj) => {
    socket.broadcast.emit(WebSocketType.GroupChat, createMessage(socket.user, messageObj.data));
  })
  socket.on(WebSocketType.SingleChat, (messageObj) => {
    Array.from(io.sockets.sockets).forEach(function (socket) {
      if (socket[1].user.username === messageObj.to) {
        socket[1].emit(WebSocketType.SingleChat, createMessage(socket[1].user, messageObj.data));
      }
    })
  })
  socket.on('disconnect', reason => {
     sendBroadList() // 发送好用列表
  });
});

function sendBroadList() {
  io.sockets.emit(WebSocketType.GroupList, createMessage(null, Array.from(io.sockets.sockets).map(item => item[1].user).filter(item=>item)))
}
// 最后filter,是因为 有可能存在null的值
  • 客户端
javascript 复制代码
const WebSocketType = {
    Error: 0, //错误
    GroupList: 1, //群列表
    GroupChat: 2, //群聊
    SingleChat: 3 //私聊
}
const socket = io(`ws://localhost:3000?token=${localStorage.getItem("token")}`);
socket.on("connect",()=>{
	socket.emit(WebSocketType.GroupList)
})
socket.on(WebSocketType.GroupList, (messageObj) => {
    select.innerHTML = ""
    select.innerHTML = `<option value="all">all</option>` + messageObj.data.map(item => `
    <option value="${item.username}">${item.username}</option>`).join("")
})
socket.on(WebSocketType.GroupChat, (msg) => {
	console.log(msg)
})
socket.on(WebSocketType.SingleChat, (msg) => {
	console.log(msg)
})
socket.on(WebSocketType.Error, (msg) => {
    localStorage.removeItem("token")
    location.href = "/login"
})
send.onclick = () => {
    if (select.value === "all") {
        socket.emit(WebSocketType.GroupChat,{
            data: text.value
        })
    } else {
        socket.emit(WebSocketType.SingleChat,{
            data: text.value,
            to:select.value
        })
    }
}
相关推荐
桂月二二4 小时前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
hunter2062066 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb6 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角6 小时前
CSS 颜色
前端·css
九酒6 小时前
从UI稿到代码优化,看Trae AI 编辑器如何帮助开发者提效
前端·trae
浪浪山小白兔7 小时前
HTML5 新表单属性详解
前端·html·html5
lee5767 小时前
npm run dev 时直接打开Chrome浏览器
前端·chrome·npm
2401_897579657 小时前
AI赋能Flutter开发:ScriptEcho助你高效构建跨端应用
前端·人工智能·flutter
limit for me8 小时前
react上增加错误边界 当存在错误时 不会显示白屏
前端·react.js·前端框架
浏览器爱好者8 小时前
如何构建一个简单的React应用?
前端·react.js·前端框架