# nodejs **Repository Path**: fw_278121/nodejs ## Basic Information - **Project Name**: nodejs - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-04-21 - **Last Updated**: 2025-10-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 1.joi 用来验证参数的库 ## 2.bcryptjs 用来加密密码的库 ```js const bcrypt = require('bcryptjs'); // 数据加密 userinfo.password = bcrypt.hashSync(userinfo.password, 10); // 数据比对 const isPasswordCorrect = bcrypt.compareSync( userinfo.password, results[0].password ); ``` ## 3.jsonwebtoken 用来生成token的库 ```js const jwt = require("jsonwebtoken"); // 生成token,里面一般包含用户的id,用户名等信息 const user = { ...results[0], password: "", user_pic: "" }; const tokenStr = jwt.sign(user, config.jwtSecretKey, { expiresIn: '10h' }); ``` ## 4.express-jwt 用来验证token的中间件 ```js // 验证token,除了api开头的接口不需要验证token,其他接口都需要验证token const { expressjwt: expressJWT } = require("express-jwt"); app.use( expressJWT({ secret: config.jwtSecretKey, algorithms: ["HS256"], }).unless({ path: [/^\/api\//] }) ); ``` ## 5.multer 用来上传文件的库 ```js const multer = require("multer"); const path = require("path"); // 配置文件上传 const storage = multer.diskStorage({ // 配置文件上传的路径 destination: (req, file, cb) => { // path.join(__dirname, "../public/uploads" :表示当前目录的上一级目录的 public/uploads 目录 // 注意:这里的路径是相对于服务器的根目录的,而不是相对于当前文件的路径的 cb(null, path.join(__dirname, "../public/uploads")); }, // 配置文件上传后的文件名 filename: (req, file, cb) => { // 获取原始文件的扩展名 const ext = path.extname(file.originalname).toLowerCase(); // 生成文件名: 时间戳-随机数.扩展名 const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9); // 允许的文件类型 const allowedExt = [ ".doc", ".docx", ".pdf", ".txt", ".jpg", ".png", ".jpeg", ]; if (!allowedExt.includes(ext)) { cb(new Error("不支持的文件类型")); return; } cb(null, uniqueSuffix + ext); }, }); // 创建 multer 实例 const upload = multer({ storage: storage }); ``` ```js // 单文件上传 const uploadSingle = (req, res, next) => { // 单文件上传 upload.single("file")(req, res, function (err) { if (err instanceof multer.MulterError) { // Multer 内部错误 return res.cc("文件上传错误:" + err.message); } else if (err) { // 自定义的扩展名错误 return res.cc(err.message); } next(); // 没出错就继续往下走 }); }; router.post("/articles/addcate", uploadSingle, getArticles.addCate); ``` ```js // 多文件上传 const uploadMultiple = (req, res, next) => { upload.array("files", 10)(req, res, function (err) { if (err instanceof multer.MulterError) { // Multer 内部错误 return res.cc("文件上传错误:" + err.message); } else if (err) { // 自定义的扩展名错误 return res.cc(err.message); } next(); // 没出错就继续往下走 }); }; router.post("/articles/add", uploadMultiple, getArticles.addArticle); ``` ## 6.sse 流式数据 ```js 1.要么不做token校验,将这个接口在全局token校验中排除掉 2.要么将token放在url上传递,但是需要放在全局的token校验前 ``` ```js // 将token放在url上传递,但是需要放在全局的token校验前 app.get("/my/stream", (req, res) => { console.log(req.query.token); // 去掉Bearer 前缀 const token = req.query.token; console.log(token); const jwt = require("jsonwebtoken"); try { const decoded = jwt.verify(token, config.jwtSecretKey); } catch (err) { res.status(401).end(); // token 无效 return; } // 开始推送 res.setHeader("Content-Type", "text/event-stream"); res.setHeader("Cache-Control", "no-cache"); res.setHeader("Connection", "keep-alive"); const chunks = [ "需求", "信息", "非常", "有限", ",", "仅", "有一个", "数字", "", "1", "2", ",", "这", "不足以", "让", ]; let i = 0; const interval = setInterval(() => { if (i < chunks.length) { res.write(`data: ${chunks[i++]}\n\n`); } else { clearInterval(interval); res.end(); } }, 1000); }); ``` ## 7.websocket ```js // 在nodejs里面使用websocket,只能借助http模块,不能使用express模块 // 如果你在 Express 中用了如下中间件:这可能会导致 WebSocket 请求被错误地当成普通 HTTP 请求拦截,从而失败! // 下面的全局中间件,会拦截所有的请求,包括websocket请求,所以需要将其放在全局中间件的前面 app.use( expressJWT({ secret: config.jwtSecretKey, algorithms: ["HS256"], }).unless({ path: [/^\/api\//] }) ); const express = require("express"); const http = require("http"); const server = http.createServer(app); const WebSocket = require("ws"); const wss = new WebSocket.Server({ server }); wss.on("connection", (ws, req) => { console.log("客户端已连接", req.url); const token = req.url.replace("/?token=", ""); const { user } = require("./router_handle/user.js"); console.log(token); if (!token) { ws.send(JSON.stringify({ error: "No token provided" })); ws.close(); return; } const decoded = jwt.verify(token, config.jwtSecretKey); if (decoded.username !== user.username) { return ws.send(JSON.stringify({ error: "Token is invalid" })); } const dataChunks = [ "需求", "信息", "非常", "有限", ",", "仅", "有一个", "数字", "", "1", "2", ",", "这", "不足以", "让", ]; let i = 0; const interval = setInterval(() => { if (i < dataChunks.length) { ws.send(dataChunks[i]); i++; } else { clearInterval(interval); ws.close(); } }, 500); // 每 500ms 发送一段文字 }); ```