node中间件-express框架

文章目录

    • 前置 Express安装
    • 1. 基本使用
    • 2. 中间件
      • 2.1 中间件应用
    • 3. 中间件的注册方式
      • 3.1 普通中间件的注册
      • 3.2 path匹配中间件
      • 3.3 method与路径匹配
      • 3.4 案列中间件匹配与执行方法
    • 4. 中间件request数据解析
      • 4.1 解析request body中间件
      • 4.2 urlencoded解析
    • 5. 第三方中间件
      • 5.1 morgan 日志记录
      • 5.2 multer 文件上传
    • 6. 参数解析 params和query
    • 7. 响应数据
    • 8. 路由
    • 9. 静态资源
    • 10 错误处理

前置 Express安装

  • 方式一 : express提供的脚手架,直接创建一个应用的骨架
  1. 安装脚手架npm install -g express-generator
  2. 创建项目 express express-demo
  3. 安装依赖npm install
  4. 启动项目 node bin/www
  • 方式二 : 从零搭建自己的express应用结构;
  1. 初始化项目 npm init
  2. 安装express npm i express

1. 基本使用

  1. 导入–>创建–>监听
  2. 使用参考文档

const express = require('express');
//  * 创建express服务器
const app=express()
//  * 启动服务器 ,监听端口app.listen(8000,()=>{console.log('启动express 服务器')
})// 请求
app.post('/login',(req,res)=>{res.end('登录成功')
})app.get('/home',(req,res)=>{res.end('home 列表模块')
})

2. 中间件

  • 中间件的本质是传递给express的一个回调函数;
  • 这个回调函数接受三个参数:
    • 请求对象(request对象);
    • 响应对象(response对象);
    • next函数(在express中定义的用于执行下一个中间件的函数);
      重要 :中间件的执行过程,只会执行第一次匹配的中间件,关于后面是否执行看next
app.post('/login', (req, res, next) => {// 中间件中的req与res可以进行修改res.aaa = '添加aaa并修改res'// 2. JSON结束// res.json({message:'登录成功',code:200})// res.end('登录成功')// 3. next 匹配执行下一个中间件next()
})
  • 注意点如果当前中间件功能没有结束请求-响应周期,则必须调用next()这将控制权传递给下一个中间件功能,否则,请求将被挂起
    在这里插入图片描述

const express = require('express');
//  * 创建express服务器
const app = express()
//  * 启动服务器 ,监听端口app.listen(8000, () => {console.log('启动express 服务器')
})// 请求
app.post('/login', (req, res, next) => {// 中间件中的req与res可以进行修改res.aaa = '添加aaa并修改res'// 2. JSON结束// res.json({message:'登录成功',code:200})// res.end('登录成功')// 3. next 匹配执行下一个中间件next()
})app.use((req,res,next)=>{console.log('执行下一个中间件next');
})app.get('/home', (req, res) => {res.end('home 列表模块')
})

2.1 中间件应用

  • express主要提供了两种方式:
    • app/router.use;
    • app/router.methods;

app.use

app.use((req,res,next)=>{console.log('执行下一个中间件next');
})

app.methods


app.get('/home', (req, res) => {res.end('home 列表模块')
})

3. 中间件的注册方式

3.1 普通中间件的注册

  • use注册的中间件不管什么路径或者请求都可以匹配的上
  • 同时在匹配的过程中如何不 next(), 只会执行第一个中间件
// 1. use注册的中间件不管什么路径或者请求都可以匹配的上
// 2. 同时在匹配的过程中如何不 next(), 只会执行第一个中间件
app.use((req,res,next)=>{console.log('执行下一个中间件next');next()
})app.use(()=>{console.log('执行第二个中间件')
})

3.2 path匹配中间件

-路径匹配中间件只是对路径做限制并没有对请求方式做显示

// 这里的路径匹配中间件只是对路径做限制并没有请求方式做显示
// 不管method如何都可以匹配 
app.use('/home',(req,res,next)=>{console.log('路径匹配中间件')
})

3.3 method与路径匹配

  • 语法: app.method(path,middleware)
  • 匹配中间件只会匹配第一个符合要求的中间件 , 关于下一个中间件是否执行看有没有调用next
// app.method(path,middleware)
app.get('/home',(req,res,next)=>{console.log('路径以及方法匹配');res.end('匹配成功')
})// 注册多个中间件
app.get('/home', (req, res, next) => {console.log('路径以及方法匹配');res.end('匹配成功')// 中间的匹配只会匹配第一个符合要求的中间件 , 关于下一个中间件是否执行看有没有调用next
}, (req, res, next)=>{console.log('关于这个中间件的执行需要看上一个中间件是否有next');
})

3.4 案列中间件匹配与执行方法

  • 普通直接写法
app.post('/login', (req, res, next) => {req.on('data', data => {let userInfo = data.toString()const user = JSON.parse(userInfo)if (user.username === 'admin' && user.password===123456) {res.end('登录成功')}else{res.end('账号或者密码错误')}})})//  注册信息
app.post('/register', (req, res, next) => {// res.end('注册成功')// 注册要查询数据库,看是否存在用户名if (true) {req.on('data', data => {let userInfo = data.toString()const user = JSON.parse(userInfo)if (user.username === 'admin' && user.password === 123456) {res.end('注册成功')} else {res.end('账号或者密码错误')}})}})
  • ** 优化 JSON解析,放到body后next()**
// 1. JSON解析,放到body
app.use((req, res, next) => {if (req.headers['content-type'] === 'application/json') {req.on('data', data => {const jsonInfo = JSON.parse(data.toString())req.body = jsonInfo})req.on('end', () => {next()})}
})// 账号密码
app.post('/login', (req, res, next) => {console.log(req.body);res.end('登录成功')
})
//  注册信息
app.post('/register', (req, res, next) => {console.log(req.body);
})

4. 中间件request数据解析

  • express有内置一些帮助我们完成对request解析的中间件;

4.1 解析request body中间件

app.use((req, res, next) => {if (req.headers['content-type'] === 'application/json') {req.on('data', data => {const jsonInfo = JSON.parse(data.toString())req.body = jsonInfo})req.on('end', () => {next()})}next()
})
// 账号密码
app.post('/login', (req, res, next) => {console.log(req.body);res.end('登录成功')
})
  • 上面代码中利用JSON.parse对data数据进行解析 ,但是 express中提供了 json可以直接进行解析
app.use(express.json())
// 账号密码
app.post('/login', (req, res, next) => {console.log(req.body);res.end('登录成功')
})

4.2 urlencoded解析

  • 解析客户端利用urlencoded传参 , 这时就需要用 express.urlencoded()
    在这里插入图片描述
app.use(express.urlencoded())  // 解析客户端利用urlencoded传参
// 解决 body - parser deprecated undefined extended: provide extended option 05urlencoded警告
app.use(express.urlencoded({ extended: true }))
app.post('/login', (req, res, next) => {console.log(req.body);res.end('登录成功')
})

5. 第三方中间件

5.1 morgan 日志记录

const express = require('express');
const morgan = require('morgan');
const fs = require('fs');
const app = express()
// cnpm i morgan  安装
// 第三方中间件 合并日志
const writerLog=fs.createWriteStream('./log.txt')
// 日志写入
app.use(morgan('combined', { stream: writerLog }))
app.post('/login', (req, res, next) => {console.log(req.body);res.end('登录成功')
})

5.2 multer 文件上传

  1. 安装 npm i multer --save
  2. Multer 只处理任何 multipart/form-data 类型的表单数据。
  3. Multer 会在express 的 request 对象里添加一个 body 对象 (包含表单的文本域信息)以及 filefiles 对象 (单文件通过req.file获取,多文件通过req.files获取,file 或 files 对象包含对象表单上传的文件信息)。
  4. 注意点 upload.single的值,对应前端name中的值,同时也要保住 form-data 中key的值相同。
const multer = require('multer');
// 对上传的文件名字重起
const upload = multer({storage: multer.diskStorage({//  文件名称, // destination 是用来确定上传的文件应该存储在哪个文件夹中// destination 是一个函数,必须创建这个文件夹destination(require, file, callback) {callback(null, 'uploads/')},filename(require, file, callback) {// originalname是文件上传时的名字,可以根据它获取后缀callback(null, Date.now() + '_' + file.originalname)}})
})
app.post('/upload', upload.single("file"), (req, res, next) => {console.log(req.file);  // 文件信息res.end('文件上传成功')
})
  • 多文件上传 ,接受的是一个数组
  • 同时在 multer实例.array(fielname[,maxCount])——接收一个以fielname命名的文件数组;maxCount——限制上传的最大数量,这些文件的信息保存在req.files里面
app.post('/upload', upload.array("file"), (req, res, next) => {console.log(req.files);  // 文件信息res.end('文件上传成功')
})

参考解析

  • storage存储引擎以及错误处理
  • 前后端上传案例

解析form-data中的普通数据

const formData=  multer()
app.post('/login',formData.any(), (req, res, next) => {console.log(req.body);  res.end('登录成功')
})

6. 参数解析 params和query

  • query 主要用于分页
app.post('/list', (req, res, next) => {// http://localhost:8000/list?offset=10&page=20解析console.log(req.query);   // { offset: '10', page: '20' }res.end('登录成功')
})
  • params 主要用于id的传递
app.post('/user/:id', (req, res, next) => {// http://localhost:8000/user/1100const id = req.params.idres.end(`获取用户${id}`)
})

7. 响应数据

  • end方式 : 类似于http中的response.end方法,用法是一致的
  • json方法 : json方法中可以传入很多的类型:object、array、string、boolean、number、null等,它们会被转换成json格式返回
  • status方法 : 用于设置状态码;注意 是函数
  • 其他响应内容参考

app.get('/login', (req, res, next) => {// 1. 方法一 end// res.end(`响应数据---登录成功`)//  2. JSON数据响应// res.json({// 	code: 0, message: '欢迎回来', data: [{// 		name: "admin",// 		avator:'www.http.ccc.jpg'// 	}]// })//  3. status 方法,设置http状态码res.status(201)res.json({code: 0, message: '欢迎回来', data: [{name: "admin",avator: 'www.http.ccc.jpg'}]})
})

8. 路由

  • express.Router来创建一个路由处理程序

useRouter.js

const express = require('express');
const userRouter = express.Router()
userRouter.get('/', (req, res, next) => {res.json({code: 0, message: 'success', data: [{name: "admin",password:'123456'}, {name: "admin",password: '123456'}]})
})
userRouter.get('/:id',(req, res, next) => {const id=req.params.idres.end(id)
})
userRouter.post('/', (req, res, next) => {
})
userRouter.delete('/:id', (req, res, next) => {
})
userRouter.patch('/:id', (req, res, next) => {})module.exports=userRouter

index.js

const userRouter = require('./router/userRouters.js');
app.use('/users', userRouter)

参考文章 :路由在项目中的具体使用

9. 静态资源

  1. express 内置static() 静态资源,直接将文件夹做一个静态资源
app.use(express.static('./uploads')) 

10 错误处理

  • 普通的错误处理,需要利用前端的数据进行if判断处理
  • 但是每一个接口写一个判断或者返回的错误信息以及状态码相同,这就会造成代码的甬余
app.post('/login', (req, res, next) => {const { username, password } = req.bodyif (username !== 'admin' || password !== 123456) {res.json({code: 1002,message: '账号密码错误'})} else {console.log('xx')res.json({code: 200,message: '登录成功'})}
})
  • 简单封装统一处理
// 中间件处理错误信息
app.post('/login', (req, res, next) => {if (username !== 'admin' || password !== 123456) {next(1002)}else {next()}
})
app.use((errCode, req, res, next) => {const code = errCodelet message = ''switch (code) {case 1001:message = '未知的错误'breakcase 1002:message = '账号或密码错误'default:message = '登录成功'}res.json({code: errCode,message,})
})

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

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

相关文章

echarts图表如何自定义鼠标悬浮样式

样式调整 // formatter: {a}: {b}<br />{c}: {d}: {e} formatter: function (params) {// <i style"display:inline-block;border-radius:50%;width:4px;height:4px;background-color: #0ECB81;"></i>// ${console.log(params[0])}return <d…

android studio JNI开发

一、JNI的作用&#xff1a; 1.使Java与本地其他类型语言&#xff08;C、C&#xff09;交互&#xff1b; 2.在Java代码调用C、C等语言的代码 或者 C、C调用Java代码。 由于JAVA具有跨平台的特点&#xff0c;所以JAVA与本地代码的交互能力弱&#xff0c;采用JNI特性可以增强JA…

【收藏】用Vue.js来构建你的Web3应用,就像开发 Web2 一样熟悉

作为一名涉足去中心化网络的前端 JavaScript 开发人员&#xff0c;您可能遇到过许多 Web3 开发解决方案。但是&#xff0c;这些解决方案通常侧重于钱包集成和交易执行&#xff0c;这就造成了学习曲线&#xff0c;偏离了熟悉的 Web2 开发体验。 但不用担心&#xff01;有一种解…

算法工程师-机器学习面试题总结(1)

一、机器学习相关 1.基本概念 1-1 损失函数是什么&#xff0c;如何定义合理的损失函数&#xff1f; 损失函数是在机器学习和优化算法中使用的一种衡量模型预测结果与真实值之间差异的函数。其目标是最小化模型的预测误差&#xff0c;从而提高模型的性能。 定义合理的损失函…

导读页——记忆之路

记忆方法千千种&#xff0c;本栏意在梳理其中道道来&#xff0c;旦有小得&#xff0c;肥肠幸耶。从不同角度分析学习记忆。 文章目录 按方法分按有无逻辑分有逻辑用思维导图 无逻辑用记忆宫殿理论模仿借鉴 按方法分 学习方法–找书&#xff0c;背书&#xff0c;利器 按有无逻…

Logback解析和实例

文章目录 1、概念2、相关依赖3、基于springboot的日志搭建3.1、yml或properties 配置3.2、 logback-spring.xml 详解3.2.1、appender 解析3.2.1.1、ConsoleAppender-控制台打印3.2.1.2、FileAppender-日志输出到文件3.2.1.3、RollingFileAppender-滚动记录并输出文件3.2.1.4、f…

8.3Java EE——基于XML的AOP实现

使用AOP代理对象的好处 因为Spring AOP中的代理对象由IoC容器自动生成,所以开发者无须过多关注代理对象生成的过程,只需选择连接点、创建切面、定义切点并在XML文件中添加配置信息即可。 Spring提供了一系列配置Spring AOP的XML元素。 配置Spring AOP的XML元素 元素 描述 &l…

FastReport.Net FastReport.Core 2023.2.23 Crack

FastReport.Net & FastReport.Core 2023.2.23适用于 .NET 7、.NET Core、Blazor、ASP.NET、MVC 和 Windows 窗体的全功能报告库。它可用于 Microsoft Visual Studio 2022 和 JetBrains Rider。 利用数据呈现领域专家针对 .NET 7、.NET Core、Blazor、ASP.NET、MVC、Windo…

MtBatis学习笔记之动态SQL

文章目录 if标签where标签trim标签set标签choose when otherwise批量删除批量插入sql标签与include标签 if标签 1、if标签中的test属性是必须的 2、if标签中test属性的值是false或者true 3、如果test是true&#xff0c;则if标签中的sql语句就会拼接&#xff0c;反之&#xff0…

Jenkins从配置到实战(二) - Jenkins如何在多台机器上自动化构建

前言 jenkins除了支持在本机上进行项目构建&#xff0c;还可以将构建任务分发到其他远程服务器上去执行&#xff0c;可以实现在不同平台和架构的机器上来完成项目的自动化构建任务&#xff0c;也能减轻jenkins服务器的压力。本文章就主要介绍下此流程。 准备工作 准备两台机…

Redis—分布式系统

Redis—分布式系统 &#x1f50e;理解分布式&#x1f50e;分布式—应用服务与数据库服务分离引入更多的应用服务节点理解负载均衡 引入更多的数据库服务节点缓存分库分表 微服务 &#x1f50e;常见概念应用(Application) / 系统(System)模块(Module) / 组件(Component)分布式(D…

支持向量机概述

支持向量机在深度学习技术出现之前,使用高斯核的支持向量机在很多分类问题上取得了很好的结果,支持向量机不仅用于分类,还可以用于回归问题。它具有泛化性能好,适合小样本和高维特征的优点。 1. SVM引入 1.1支持向量机分类 支持向量机的基本模型是定义在特征空间上的间隔…

【笔记】markdown易忘速查(对勾/表格/符号/流程图)

https://www.runoob.com/markdown/md-tutorial.html 这里有较系统的免费教程&#xff0c;本篇只是个人的使用备忘录&#xff0c;仅供参考 目录 mark易忘速查目录表格链接符号公式流程/时序/甘特图 mark易忘速查 目录 [toc](目录名称)目录演示 mark易忘速查目录表格链接符号公…

2023年最全OCR技术指南!预训练OCR大模型呼之欲出

OCR是一项科技革新&#xff0c;通过自动化大幅减少人工录入的过程&#xff0c;帮助用户从图像或扫描文档中提取文字&#xff0c;并将这些文字转换为计算机可读格式。这一功能在许多需要进一步处理数据的场景中&#xff0c;如身份验证、费用管理、自动报销、业务办理等都显得尤为…

【Linux】多线程概念理论

目录 1 什么是线程&#xff1f; 2 线程的优点 3 线程的缺点 4 线程异常 5 线程用途 6 Linux线程和进程对比 1 什么是线程&#xff1f; 在一个程序里的一个执行路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程是“一个进程内部的控制序列…

网关与路由器的区别

仅需2分钟&#xff0c;彻底明白网关的工作原理_哔哩哔哩_bilibili网关_百度百科 一、网关的概念 网关(Gateway)又称网间连接器、协议转换器。网关在网络层以上实现网络互连&#xff0c;是复杂的网络互连设备&#xff0c;仅用于两个高层协议不同的网络互连。网关既可以用于广域…

【目标跟踪】1、基础知识

文章目录 一、卡尔曼滤波二、匈牙利匹配 一、卡尔曼滤波 什么是卡尔曼滤波&#xff1f;——状态估计器 卡尔曼滤波用于在包含不确定信息的系统中做出预测&#xff0c;对系统下一步要做什么进行推测&#xff0c;且会结合推测值和观测值来得到修正后的最优值卡尔曼滤波就是利用…

TypeScript基础篇 - Vue-TS-Webpack 环境实战

目录 WebpackVueTS 环境配置 scripts/webpack.config.js src/Hello.tsx src/SfcDemo.vue src/main.tsx src/shims-vue.d.ts package.json WebpackVueTS 环境配置 scripts/webpack.config.js const path require(path) // 安装插件 npm install webpack webpack-cli b…

VS Code 设置大小写转换快捷键

VS Code 设置大小写转换快捷键 前言&#xff1a;VS Code 没有默认的大小写转换快捷键&#xff0c;需要我们自己添加。 一 、打开快捷键设置面板 二、添加快捷键 在搜索框输入 “转换为大写”&#xff0c;如果您的VS Code没有汉化&#xff0c;此处输入“Transform to Uppercase…

SQL中的替换函数replace将字段中的匹配值进行替换

目录 一、更新替换 二、查询替换 一、更新替换 UPDATE 表名 SET 字段名 REPLACE(字段名,匹配值,替换值) WHERE id 1 例&#xff1a;将user表中的address字段中IP1替换为IP2 UPDATE user SET address REPLACE(address,IP1,IP2) 二、查询替换 SELECT *,REPLACE(字段名,…