nodejs fs http express express-session jwt mysql mongoose

文件fs模块

读取文件内容

fs.readFile('./file/fs-01.txt', 'utf8', (err, data) => {if (err) {console.error(err)return}console.log(data)
})

写入内容到文件

const fs = require('fs');const filePath = "./file/output.txt";fs.writeFile(filePath, "Hello World", {mode: 0o666,flag: 'a'},(err) => {if (err) {console.log(err);} else {console.log("File written successfully");}
});

path模块使用


const path = require("path");
const fs = require("fs");let absolutPath = path.join(__dirname,"file","output.txt");
// 绝对路径
console.log(absolutPath);
// 文件名 output.txt
console.log(path.basename(absolutPath));
// 扩展名 .txt
console.log(path.extname(absolutPath));fs.readFile(absolutPath,{encoding:'utf-8'},(err,data) => {if (err){console.log('read fail')return 0;}console.log('read success:',data);const split = data.split(" ");if (split.length < 0){return 0;}let arr = [];split.forEach(item=>{arr.push(item.replace("=",":"));});let join = arr.join("\r\n");console.log(join);});

正则表达式匹配

// \s 匹配任意空白字符 \S 匹配任意非空白字符
let styleReg = /<style>[\s\S]*<\/style>/;

http模块

const http = require("http");
const fs = require("fs");
const path = require("path");let server = http.createServer();
server.on("request",(req,res) => {// 设置响应头res.setHeader("Content-Type","text/html;charset=utf-8");// 响应内容变量let content = "<h1>404</h1>";// 获取客户端请求的URL地址let url = req.url;if ("/favicon.ico" === url){return 0;}else if ("/" === url){url = "/index.html";}const fPath = path.join(__dirname,"file",url);console.log(fPath);fs.readFile(fPath,"utf-8",(err,data) => {if (err){console.log("request err:",err);res.end(content);}else {content = data;res.end(content);}})
});server.listen(8080,() => {console.log("server start http://localhost:8080")
});

module使用

定义

console.log("我是m1模块");
// console.log(module);function sum(a,b){return a+b;
}function sayHello(){console.log("sayHello...");return 1;
}const uname= "我是妹妹";// 暴露模块,最终共享的结果以module.exports为准
module.exports = {sum,uname,sayHello
}
// module.exports.uname = "我是妹妹";

使用

const m1 = require("./m1");console.log(m1.sum(1,2));
m1.sayHello();
console.log(m1.uname);

image.png
最终共享的结果以module.exports为准
image.png

CommonJS规范

image.png

npm和包

image.png

安装cnpm

npm install -g cnpm --registry=https://registry.npm.taobao.org

安装

// 安装最新
npm i/install moment
// 安装指定版本
// 查看版本
// npm view 包名 versions
npm view moment versions
['1.0.0',  '1.0.1',  '1.1.0',  '1.1.1',  '1.2.0','1.3.0',  '1.4.0',  '1.5.0',  '1.5.1',  '1.6.0','1.6.1',  '1.6.2',  '1.7.0',  '1.7.1',  '1.7.2','2.0.0',  '2.1.0',  '2.2.1',  '2.3.0',  '2.3.1','2.4.0',  '2.5.0',  '2.5.1',  '2.6.0',  '2.7.0','2.8.1',  '2.8.2',  '2.8.3',  '2.8.4',  '2.9.0','2.10.2', '2.10.3', '2.10.5', '2.10.6', '2.11.0','2.11.1', '2.11.2', '2.12.0', '2.13.0', '2.14.0','2.14.1', '2.15.0', '2.15.1', '2.15.2', '2.16.0','2.17.0', '2.17.1', '2.18.0', '2.18.1', '2.19.0','2.19.1', '2.19.2', '2.19.3', '2.19.4', '2.20.0','2.20.1', '2.21.0', '2.22.0', '2.22.1', '2.22.2','2.23.0', '2.24.0', '2.25.0', '2.25.1', '2.25.2','2.25.3', '2.26.0', '2.27.0', '2.28.0', '2.29.0','2.29.1', '2.29.2', '2.29.3', '2.29.4', '2.30.0','2.30.1'
]npm i moment@2.30.0

image.png

解决包下载慢问题

image.png

开发自己的包

image.png

发布包到npm

要将包发布到 npm ,可以按照以下步骤进行操作:

  1. 确保你已经注册了 npm 账号。
  2. 创建一个具有适当结构和功能的包。
  3. 在项目根目录下运行 npm login 命令,使用你的 npm 账号登录。
  4. 编辑 package.json 文件,确保其中包含必要的信息,如包的名称、描述、版本等。
  5. 在命令行中进入项目根目录。
  6. 运行 npm publish 命令来发布包。
  7. 等待发布过程完成。

发布包到 npm 后,其他开发者就可以通过 npm install 命令安装你的包了。

在发布之前,还需要注意以下几点:

  • 确保包的质量和稳定性。
  • 遵循 npm 的最佳实践和规范。
  • 仔细阅读 npm 的文档,了解相关的规定和限制。
  • 对包进行充分的测试。

模块加载机制

image.png

express框架

托管静态资源

image.png

const express = require("express");
const path = require("path");const app = express();// 托管静态资源
app.use(express.static(path.join(__dirname,"../../public")));const server = app.listen(8080,()=>{let address = server.address().address;let port = server.address().port;console.log("server express : http://127.0.0.1:%s",port);
});

托管多个静态资源

image.png
image.png

nodemon

Nodemon 是一个用于开发 Node.js 应用程序的实用工具。它的主要功能是在代码更改时自动重新启动 Node.js 服务器,以便你能够实时看到代码更改的效果。

以下是使用 Nodemon 的一般步骤:

  1. 安装 Nodemon:可以使用包管理工具(如 npm)进行安装。
npm install nodemon
  1. 在命令行中使用 Nodemon 启动你的 Node.js 应用程序。
nodemon your_script.js

其中 your_script.js 是你的 Node.js 脚本文件。

  1. Nodemon 会监控你的代码文件更改,并在保存时自动重新启动服务器。

使用 Nodemon 的好处包括:

  • 实时反馈:你可以立即看到代码更改的效果,无需手动重新启动服务器。
  • 提高开发效率:减少了手动重新启动服务器的时间和麻烦。
  • 方便调试:能够快速发现和解决问题。

请注意,Nodemon 还有许多其他配置选项,可以根据你的具体需求进行调整。

模块化路由

image.png

router.js

let express = require("express");let router = express.Router();router.get('/user',function (req,res){res.send("user");
});router.post("/about",function (req,res){res.send("about");
});module.exports = router;
// module.exports = {
//     router
// }

index.js

const express = require("express");
const router = require("./router");const app = express();//注册路由
app.use(router);
//注册路由,加访问前缀
// app.use("/api",router);app.listen(8080,()=>{console.log("server express : http://127.0.0.1:8080");
});

路由加前缀

image.png

中间件

const express = require("express");
const moment = require("moment");const router = require("./router");const app = express();// 中间件
const requestTime = function (req,res,next){req.requestTime = moment(new Date()).format("YYYY-MM-DD HH:mm:ss")next()
}
app.use(requestTime)
//注册路由
app.use("/api",router);app.listen(8080,()=>{console.log(moment(new Date()).format("YYYY-MM-DD HH:mm:ss"))console.log("server express : http://127.0.0.1:8080");
});
let express = require("express");let router = express.Router();router.get('/user',function (req,res){// 打印中间件参数console.log("requestTime:",req.requestTime)res.send("user");
});router.post("/about",function (req,res){res.send("about");
});module.exports = router;
// module.exports = {
//     router
// }

中间件全局生效

image.png

中间件局部生效

image.png

router.get('/middleware',function (req,res,next){console.log("局部中间件");next();
},function (req,res){res.send("middleware");
})

image.png
image.png

中间件的分类

image.png

应用级别

绑定在app身上

路由级别

绑定在路由router身上

错误级别

// 错误中间件必须注册在路由之后
image.png

const express = require("express");
const app = express();app.get('/',(req,res)=>{throw new Error("发送错误");
})app.get('/user',(req,res)=>{res.send("user page");
})
// 错误中间件必须注册在路由之后
app.use(function (err,req,res,next){console.log("异常级别中间件");if (err){res.send('err:'+err.message);next();}
});app.listen(8080,()=>{console.log("server express : http://127.0.0.1:8080");
});

express内置中间件

image.png

const express = require("express");
const app = express();//中间件
// 用来解析application/json表单的中间件
app.use(express.json())
// 用来解析x-www-from-urlencoded表单的中间件
app.use(express.urlencoded())app.post('/user',(req,res)=>{let body = req.body;// 如果没有配置解析表单的中间件,body是undefinedconsole.log(body)res.send("user page");
})app.listen(8080,()=>{console.log("server express : http://127.0.0.1:8080");
});

第三方中间件

image.png

const express = require("express");
// const path = require("path");
const bodyParser = require("body-parser");const app = express();app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}))app.post('/index',function (req,res){console.log(req.body);res.send("index");
});app.listen(8080,()=>{console.log("server express : http://127.0.0.1:8080");
});

自定义中间件

image.png

监听req的data事件

image.png
image.png

完整代码
const express = require("express");
const querystring= require("querystring");const app = express();// 解析表单数据的中间件
app.use(function (req,res,next){let formData= "";req.on("data",(chunk)=>{formData += chunk;})req.on("end",()=>{console.log(formData);let body = querystring.parse(formData);console.log(body);req.body = body;next();})
})app.post('/index',function (req,res){console.log(req.body);console.log(req.body.bookname);res.send("index");
});app.listen(8080,()=>{console.log("server express : http://127.0.0.1:8080");
});

练习

apiRouter.js
index.js

cors问题

image.png

cnpm install cors
const cors = require('cors')
app.use(cors())

cors三个响应头

image.png
image.png
image.png
image.png
image.png

jsonp解决跨越

image.png
JSONP 是 JSON 的一种使用模式,全称为 JSON with Padding,即“带回调的 JSON”。它可以绕过浏览器的同源策略,进行跨域请求。
JSONP 利用了

express-session会话

// 安装session
// cnpm install express-sessionconst express = require("express");
// 导入 session
const session = require("express-session");const app = express();app.use(express.json())
app.use(express.urlencoded({extended: false}))// 配置 session
app.use(session({secret: 'test123',//任意resave: true,//固定saveUninitialized: true //固定
}))app.post('/api/login',(req,res)=>{// 验证登录if (req.body.username !== 'admin' || req.body.password !== '000000'){return res.send({status: 1,msg: "登录失败"});}// 存储会话// 配置了express-session,可以存储sessionreq.session.user = req.body;req.session.isLogin = true;return res.send({status: 0,msg: "登录成功"});
})app.get('/api/username',(req,res)=>{if (!req.session.isLogin){return res.send({status: 1,msg: "没有登录"});}return res.send({status: 0,msg: "获取成功",data: req.session.user.username});
})app.get('/api/logout',(req,res)=>{if (!req.session.isLogin){return res.send({status: 1,msg: "没有登录"});}// 清空sessionreq.session.destroy();return res.send({status: 0,msg: "ok"});
})app.listen(8080,()=>{console.log("server start:http://localhost:8080");
})

jwt认证

image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png

const crypto = require("crypto");
module.exports = {MD5_SUFFIX: "tangzhenhua",md5: pwd => {let md5 = crypto.createHash("md5");return md5.update(pwd).digest("hex");},secretKey: "tangzhenhua",
};
const { secretKey } = require("./salt");
const jwt = require("jsonwebtoken");
const {expressjwt} = require("express-jwt");
// 生成 token
const createToken = payload => jwt.sign(payload, secretKey, { expiresIn: 60 * 60 * 240 });
// 验证 token
const jwtAuth = expressjwt({secret: secretKey,algorithms: ["HS256"],credentialsRequired: true,
});
// 不需要校验的路径
jwtAuth.unless({ path:("/api/login") });module.exports = { jwtAuth, createToken };
// cnpm install jsonwebtoken express-jwtconst express = require("express");
// jwt相关
let { jwtAuth,createToken } = require("./util");const app = express();app.use(jwtAuth);
app.use(express.json())
app.use(express.urlencoded({extended: false}))app.post('/api/login',(req,res)=>{// 验证登录if (req.body.username !== 'admin' || req.body.password !== '000000'){return res.send({status: 1,msg: "登录失败"});}let token = createToken({username: req.body.username})console.log("token=",token)return res.send({status: 0,msg: "登录成功",token: token});
})app.get('/admin/getUserInfo',(req,res)=>{let userInfo = req.user;return res.send({status: 0,msg: "获取成功",data: userInfo});
})// 错误处理中间件,处理 JWT 鉴权失败
app.use((err, req, res, next) => {if (err.name === 'UnauthorizedError') {res.status(401).json({error: 'Invalid token'});}
});app.listen(8080,()=>{console.log("server start:http://localhost:8080");
})

MySQL模块

安装mysql

cnpm install mysql
const mysql = require('mysql');
const connection = mysql.createConnection({host: 'localhost',port: 3306,user: 'root',password: 'root',database: 'test'
});connection.connect((err) => {if (err) throw err;console.log('Connected!');// 查询connection.query('SELECT * FROM users', (err, rows) => {if (err) throw err;console.log('Data received from MySQL:', rows);});// 新增// let sql = 'insert into users(username, password) values (?,?)';// let inserts = ['test', '123456'];// sql = mysql.format(sql, inserts);// console.log("sql=>",sql);// connection.query(sql,function (err,result){//     if (err) throw err;//     console.log('--------------------------INSERT----------------------------');//     console.log('INSERT ID:',result);//     console.log('------------------------------------------------------------\n\n');// })// 更新// let updateSql = "update users set username = ? ,password = ? where id = 3";// let updateSqlParams = ['crazyfur','654321'];// connection.query(updateSql,updateSqlParams,function (err,result){//     if (err) throw err;//     console.log('--------------------------UPDATE----------------------------');//     console.log('UPDATE affectedRows',result.affectedRows);//     console.log('------------------------------------------------------------\n\n');// })// 删除let delSql = "delete from users where id = 3";connection.query(delSql,(err,result)=>{if (err) throw err;console.log('--------------------------DELETE----------------------------');console.log('DELETE affectedRows',result.affectedRows);console.log('------------------------------------------------------------\n\n');})// 关闭连接connection.end((err) => {if (err) {console.error('Error occurred while closing the connection:', err);} else {console.log('Connection closed successfully.');}});
});

image.png

项目实战

表单校验

npm install joi
npm i @escook/express-joi
https://blog.csdn.net/doiido/article/details/131967068

定义

const joi = require("joi");/*** string() 值必须是字符串* alphanum() 值只能是包含 a-zA-Z0-9 的字符串* min(length) 最小长度* max(length) 最大长度* required() 值是必填项,不能为 undefined* pattern( 正则表达式 ) 值必须符合正则表达式的规则*/// 用户名的验证规则
const username = joi.string().alphanum().min ( 1 ). max ( 10 ).required ()
// 密码的验证规则
const password = joi.string().pattern( /^\S{6,12}$/ ).required ()
// 注册和登录表单的验证规则对象
exports.reg_login_schema = {// 表示需要对 req.body 中的数据进行验证body : {username ,password ,},
}

使用

const express = require("express")const router = express.Router()const userHandler = require("../router_handler/user")// 1. 导入验证表单数据的中间件
const expressJoi = require ( '@escook/express-joi' )
// 2. 导入需要的验证规则对象
const { reg_login_schema } = require ( '../schema/user' )
// 3. 使用规则
router.post("/register",expressJoi(reg_login_schema),userHandler.userRegister)
router.post("/login",userHandler.userLogin)module.exports = router;

mongoose

npm install mongoose
let mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test').then(()=>{console.log("ok")
}).catch(err=>{console.log(err);
});//监听数据库连接状态
mongoose.connection.once('open',()=>{console.log('数据库连接成功……')const Schema = mongoose.Schema;//创建Schema对象(约束)let stuSchema = new Schema({name: String,age: Number,gender:{type: String,default:'male',required: true},addr: String,},{timestamps:true})//将stuSchema映射到一个MongoDB collection并定义这个文档的构成let StuModule = mongoose.model('student',stuSchema);new StuModule({name: '小明',age: 18,addr: '北京'}).save().then((result)=>{console.log(result)}).catch(err=>{console.log(err);})})mongoose.connection.once('close',()=>{console.log('数据库断开……')
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/803748.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[C++][算法基础]字符串统计(Trie树)

维护一个字符串集合&#xff0c;支持两种操作&#xff1a; I x 向集合中插入一个字符串 x&#xff1b;Q x 询问一个字符串在集合中出现了多少次。 共有 N 个操作&#xff0c;所有输入的字符串总长度不超过 &#xff0c;字符串仅包含小写英文字母。 输入格式 第一行包含整数…

MySQL-10. 存储引擎、视图、mysql管理

10.1 存储引擎 存储引擎说白了就是如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法。因为在关系数据库中数据的存储是以表的形式存储的&#xff0c;所以存储引擎也可以称为表类型&#xff08;即存储和操作此表的类型&#xff09;。 存储引擎(Stor…

【MySQL】C# 连接MySQL

C# 连接MySQL 1. 添加MySQL引用 安装完MySQL之后&#xff0c;在安装的默认目录 C:\Program Files (x86)\MySQL\Connector NET 8.0 中查找MySQLData.dll文件。 在Visual Studio 中为项目中添加引用。 2. 引入命名空间 using MySql.Data.MySqlClient;3. 构建连接 private …

spring boot admin搭建,监控springboot程序运行状况

新建一个spring boot web项目&#xff0c;添加以下依赖 <dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-server</artifactId><version>2.3.0</version></dependency> <dependency&…

微信小程序自定义tabbar,页面切换存在闪动【解决方案】

需求&#xff1a; 自定义tabbar&#xff0c;在需要的几个主页面都加入这么一个组件&#xff0c;但是有个情况&#xff1b;而组件中使用照片&#xff08;svg或png&#xff09;和文字;在切换tabbar的时候&#xff0c;跳转相应的页面&#xff0c;运行到真机或是模拟器&#xff0c;…

Go —— channel (二)

一个空的 channel 会产生哪些问题 读写nil管道均会阻塞触发死锁。关闭的管道仍然可以读取数据&#xff0c;向关闭的管道写数据会触发panic。 问&#xff1a;如果有多个协程同时读取一个channel&#xff0c;channel会如何选择消费者 channel 会按照维护的 recvq 等待读消息的…

苍穹外卖11(Apache ECharts前端统计,营业额统计,用户统计,订单统计,销量排名Top10)

目录 一、Apache ECharts【前端】 1. 介绍 2. 入门案例 二、营业额统计 1. 需求分析和设计 1 产品原型 2 业务规则 3 接口设计 2. 代码开发 3. 功能测试 三、用户统计 1. 需求分析和设计 1 产品原型 2 业务规则 3 接口设计 2. 代码开发 3. 功能测试 四、订单统…

0.开篇:SSM+Spring Boot导学

1. 为什么要使用框架 Spring是一个轻量级Java开发框架&#xff0c;最早有Rod Johnson创建&#xff0c;目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。 几乎当下所有企业级JavaEE开发都离不开SSM&#xff08;Spring SpringMVC MyBatis&#xff09;Spring B…

什么是企业邮箱?如何选择合适的企业邮箱?

企业邮箱和个人邮箱不同&#xff0c;它的邮箱后缀是企业自己的域名。企业邮箱供应商一般都提供手机app、桌面端、web浏览器访问等邮箱使用途径。那么什么是企业邮箱&#xff1f;如何选择合适的企业邮箱&#xff1f;好用的企业邮箱应具备无缝迁移、协作、多邮箱管理等功能。 企…

STM32-模数转化器

ADC(Analog-to-Digital Converter) 指模数转换器。是指将连续变化的模拟信号转换 为离散的数字信号的器件。 ADC相关参数说明&#xff1a; 分辨率&#xff1a; 分辨率以二进制&#xff08;或十进制&#xff09;数的位数来表示&#xff0c;一般有 8 位、10 位、12 位、16 位…

Transformer模型-decoder解码器,target mask目标掩码的简明介绍

今天介绍transformer模型的decoder解码器&#xff0c;target mask目标掩码 背景 解码器层是对前面文章中提到的子层的包装器。它接受位置嵌入的目标序列&#xff0c;并将它们通过带掩码的多头注意力机制传递。使用掩码是为了防止解码器查看序列中的下一个标记。它迫使模型仅使用…

WPF 多语言切换及ResourceDictionary的Source路径填写

WPF 多语言切换 1. 添加资源字典 新增两个资源字典&#xff0c;里面分别存储不同语言的文本 <ResourceDictionary xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s…

使用API有效率地管理Dynadot域名,确认域名转移流程状态

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮…

虚拟网络设备与网络安全:深入分析与实践应用

在数字化时代&#x1f4f2;&#xff0c;网络安全&#x1f512;成为了企业和个人防御体系中不可或缺的一部分。随着网络攻击的日益复杂和频繁&#x1f525;&#xff0c;传统的物理网络安全措施已经无法满足快速发展的需求。虚拟网络设备&#x1f5a7;&#xff0c;作为网络架构中…

计算机网络——39密钥分发和证书

密钥分发和证书 可信赖中介 对称密钥问题 相互通信的实体如何分享对称密式的密钥&#xff1f; 解决办法 trusted key distribution center(KDC) 在实体之间扮演可信赖中介的角色 公共密钥问题 当Alice获得Bob的公钥(from web site,e-mail,diskette)&#xff0c;她如何知…

16、普通数组-除自身以外的数组乘积

思路 通过辅助数组的方式 第一个从左向右的辅助数组乘积第二次从右向左的辅助数组乘积对于0<i<N-1 他的数组乘积就是左边的数组乘积*右边数组乘积然后再分类讨论i0 就是右边1-N-1的数组乘积iN-1就是左边从N-2到0的数组乘积 代码如下&#xff1a; class Solution {pub…

C# 优雅的处理 TCP 数据

前言 Tcp是一个面向连接的流数据传输协议&#xff0c;用人话说就是传输是一个已经建立好连接的管道&#xff0c;数据都在管道里像流水一样流淌到对端。 那么数据必然存在几个问题&#xff0c;比如数据如何持续的读取&#xff0c;数据包的边界等。 Nagles算法 Nagle 算法的核…

电商技术揭秘十五:数据挖掘与用户行为分析

相关系列文章 电商技术揭秘一&#xff1a;电商架构设计与核心技术 电商技术揭秘二&#xff1a;电商平台推荐系统的实现与优化 电商技术揭秘三&#xff1a;电商平台的支付与结算系统 电商技术揭秘四&#xff1a;电商平台的物流管理系统 电商技术揭秘五&#xff1a;电商平台…

vue2 使用vue-org-tree demo

1.安装 npm i vue2-org-tree npm install -D less-loader less安装 less-loader出错解决办法&#xff0c;直接在package.json》devDependencies下面加入less和less-loader版本&#xff0c;然后执行npm i &#xff0c;我用的nodejs版本是 16.18.0&#xff0c;“webpack”: “^4…

Tomcat SSL/TLS Configuration

see https://tomcat.apache.org/tomcat-9.0-doc/ssl-howto.html//1:use jdk keytool A:Generate Keystore 01: C:\Users\User>keytool -genkey -alias tomcat -keyalg RSA -keystore d:/ks/tomcatKeyStore //也可参考:keytool -genkeypair -alias "tomcat" -k…