第三方Express 路由和路由中间件

文章目录

  • 1、Express 应用使用回调函数的参数: request 和 response 对象来处理请求和响应的数据。
  • 2、Express路由
    • 1.路由方法
    • 2.路由路径
    • 3.路由处理程序
  • 3. 模块化路由
  • 4. Express中间件
    • 1.中间件简介
    • 2.中间件分类
    • 3.自定义中间件


1、Express 应用使用回调函数的参数: request 和 response 对象来处理请求和响应的数据。

  1. Request 对象
    request 对象表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性
    属性/方法说明
    app当callback为外部文件时,用req.app访问express的实例
    baseUrl获取路由当前安装的URL路径
    body/cookies获得「请求主体」/ Cookies
    fresh/stale判断请求是否还「新鲜」
    hostname/ip获取主机名和IP地址
    originalUrl获取原始请求URL
    params获取路由的parameters
    path获取请求路径
    protocol获取协议类型
    query获取URL的查询参数串
    route获取当前匹配的路由
    subdomains获取子域名
    accepts()检查可接受的请求的文档类型
    acceptsCharsets/acceptsEncodings/acceptsLanguages返回指定字符集的第一个可接受字符编码
    get()获取指定的HTTP请求头
    is()判断请求头Content-Type的MIME类型
  2. Response 对象
    response 对象表示 HTTP 响应,即在接收到请求时向客户端发送的 HTTP 响应数据
    属性/方法说明
    app当callback为外部文件时,用req.app访问express的实例
    append()追加指定HTTP头
    set()在res.append()后将重置之前设置的头
    res.cookie(name,value [,option])设置Cookie
    opitiondomain / expires / httpOnly / maxAge / path / secure / signed
    clearCookie()清除Cookie
    download()传送指定路径的文件
    get()返回指定的HTTP头
    json()传送JSON响应
    jsonp()传送JSONP响应
    location()只设置响应的Location HTTP头,不设置状态码或者close response
    redirect()设置响应的Location HTTP头,并且设置状态码302
    render(view,[locals],callback)渲染一个view,同时向callback传递渲染后的字符串,如果在渲染过程中有错误发生next(err)将会被自动调用。callback将会被传入一个可能发生的错误以及渲染后的页面,这样就不会自动输出了。
    send()传送HTTP响应
    sendFile(path [,options] [,fn])传送指定路径的文件 -会自动根据文件extension设定Content-Type
    set()设置HTTP头,传入object可以一次设置多个头
    status()设置HTTP状态码
    type()设置Content-Type的MIME类型

2、Express路由

路由是指应用程序的终端节点 (URI) 如何响应客户端请求。
在Express中,路由指的是客户端的请求与服务器处理函数之间的映射关系。
Express中的路由分3部分组成,分别是请求的类型、请求的URL地址、处理函数,格式如下:app.method(path, handler)

1.路由方法

// GET method route
app.get('/', function (req, res) {res.send('GET request')
})// POST method route
app.post('/', function (req, res) {res.send('POST request')
})

app.all() 用于在所有 HTTP 请求方法的路径上加载中间件函数。
无论是使用 GET、POST、PUT、DELETE 还是 http 模块中支持的任何其他 HTTP 请求方法,都会对路由 “/secret” 的请求执行以下处理程序。

app.all('/secret', function (req, res, next) {console.log('all')next() // pass control to the next handler
})

2.路由路径

路由路径可以是字符串、字符串模式或正则表达式。

// acd和abcd
app.get('/ab?cd', function (req, res) {res.send('ab?cd')
})

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总结:问号前面字符可有可无

app.get('/ab(cd)?e', function (req, res) {res.send('ab(cd)?e')
})

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总结:问号前面括号内的字符可有可无

app.get('/ab+cd', function (req, res) {res.send('ab+cd')
})

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总结:加号前面字符可无限叠加

app.get('/ab*cd', function (req, res) {res.send('ab*cd')
})

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总结:星号前面的字符为开始,后边的字符为结束字符,中间可以任意字符或数字

app.get(/a/, function (req, res) {res.send('/a/')
})

在这里插入图片描述
在这里插入图片描述
总结:满足正则/a/的都满足此方法

app.get(/.*fly$/, function (req, res) {res.send('/.*fly$/')
})

在这里插入图片描述
在这里插入图片描述

总结:满足正则/.*fly$/以fly字符结束的路由

3.路由处理程序

在没有理由继续当前路由时将控制权传递给后续路由。next(‘route’)
路由处理程序可以采用函数、函数数组或两者的组合形式。

  1. 单个回调函数可以处理路由。

    var express = require('express');
    var app = express();
    app.get('/abc', function (req, res) {res.send('hello abc');
    })
    app.listen(8081, function () {console.log("服务启动")
    })
    
  2. 多个回调函数可以处理一个路由(确保指定对象)next();

    var express = require('express');
    var app = express();
    app.get('/abc', function (req, res, next) {console.log(111)next()
    }, function(req, res) {res.send('hello abc next');
    })
    app.listen(8081, function () {console.log("服务启动")
    })	
    

    在这里插入图片描述
    在这里插入图片描述

  3. 回调函数数组可以处理路由。

    var express = require('express');
    var app = express();
    var a0 = function (req, res, next) {console.log('A0')next()
    }
    var a1 = function (req, res, next) {console.log('A1')next()
    }
    var a2 = function (req, res) {res.send('Hello from A!')
    }
    app.get('/abc', [a0, a1, a2])
    app.listen(8081, function () {console.log("服务启动")
    })
    

    在这里插入图片描述
    在这里插入图片描述

  4. 独立函数和函数数组的组合可以处理路由。

    var express = require('express');
    var app = express();
    var a1 = function (req, res, next) {console.log('A1')next()
    }
    var a2 = function (req, res) {res.send('Hello from A!')
    }
    app.get('/abc', function (req, res, next) {console.log('A0')next()
    },[a1, a2])
    app.listen(8081, function () {console.log("服务启动")
    })
    

    在这里插入图片描述
    在这里插入图片描述

3. 模块化路由

为了方便对路由进行模块化的管理,Express不建议将路由直接挂载到app上,而是推荐将路由抽离为单独的模块。

将路由抽离为单独模块的步骤如下:
1.创建路由模块对应的.js文件
2.调用express.Router()函数创建路由对象
3.向路由对象上挂载具体的路由
4.使用module.exports向外共享路由对象
5.使用app.use()函数注册路由模块

  1. 创建路由模块
    // router.js   文件
    var express = require('express'); // 1.导入express
    var router = express.Router();    // 2.创建路由对象router.get('/login/info', (req, res) => {   // 3.挂载登录用户信息res.send('Get user list.');
    });
    router.post('/singUp/add', (req, res) => {   // 4.挂载注册用户的路由res.send('Add new user.');
    });
    module.exports = router;  // 5.向外导出路由对象
    
  2. 注册路由模块
    const express = require('express');
    const app = express();
    // 1.导入路由模块
    const userRouter = require('./router.js');
    // 2.使用app.use()注册路由模块
    app.use(userRouter);
    app.listen(8081, () => {console.log('http://127.0.0.1')
    })
    
  3. 为路由模块添加前缀
    // 类似于托管静态资源时,为静态资源统一挂载访问前缀一样
    // 1.导入路由模块
    const userRouter = require('./router.js');
    // 2.使用app.use()注册路由模块,并添加统一的范围前缀 /api 
    app.use('/api', userRouter);
    

4. Express中间件

1.中间件简介

  1. 中间件简介
    中间件是一种特殊的路由处理函数,它可以在请求到达目标处理函数之前,进行一些预处理操作。Express 支持使用中间件来实现各种功能,例如身份验证、请求日志记录,处理 CORS(跨源资源共享)等。
    注意:中间件函数的形参列表中,必须包含next参数,而路由处理函数中只包含req和res。
    next函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件或路由。
    可以使用app.use()连续定义多个全局中间件。客户端请求到达服务器之后,会按照中间件定义的先后顺序依次进行调用
    const express = require('express');
    const app = express();
    // 一个简单的中间件
    app.use((req, res, next) => {console.log(`Request received at ${new Date()}`);next(); // 将控制权传递给下一个中间件或路由处理器
    });
    // 一个路由处理器,用于处理 GET 请求
    app.get('/', (req, res) => {res.send('Hello, World!');
    });// 启动服务器
    app.listen(8081, () => {console.log('Server is running on port 8081');
    });
    
    在这里插入图片描述
  2. 局部中间件
    不使用app.use()定义的中间件,叫做局部生效的中间件, 中间件只在"当前路由中生效",
    var express = require('express');
    var app = express();var myLogger = function (req, res, next) {console.log('LOGGED')next()
    }
    app.get('/', myLogger, function (req, res) {res.send('Hello World!')
    })
    
    在这里插入图片描述
  3. 中间件的5个使用注意事项
    • 一定要在路由之前注册中间件
    • 客户端发送过来的请求,可以连续调用多个中间件进行处理
    • 执行完中间件的业务代码之后,不要忘记调用next()函数
    • 为了防止代码逻辑混乱,调用next()函数后不要再写额外的代码
    • 连续调用多个中间件时,多个中间件之间,共享req和res对象
  4. 监听 req 的 data 事件
    在中间件中,需要监听req对象的data事件,来获取客户端发送到服务器的数据。
    如果数据量比较大,无法一次性发送完毕,则客户端会把数据切割后,分批发送到服务器。所以data事件可能会触发多次,每一次触发data事件时,获取到数据只是完整数据的一部分,需要手动对接收到的数据进行拼接。
    // 定义变量,用来储存客户端发送过来的请求体数据
    let str = ''
    // 监听 req 对象的 data 事件(客户端发送过来的新的请求体数据)
    req.on('data',(data) => {// 打印请求数据console.log(data)
    })
    
  5. 监听 req 的 end 事件
    当请求体数据接收完毕之后,会自动触发req的end 事件。
    可以在req的end 事件中,拿到并处理完整的请求体数据。
    // 监听 req 对象的 end 事件(请求体发送完毕后自动触发)
    req.on('end',() => {// => 打印完整的请求体数据console.log(str)// TODO: 业务逻辑// .......
    })
    

2.中间件分类

  1. 应用程序级中间件
    通过app.use()或app.get()或 app.post(),绑定到app实例上的中间件,叫做应用级别的中间件,
    var app = express();
    var myLogger = function (req, res, next) {console.log('LOGGED')next()
    }
    // 应用级别的中间件(全局中间件)
    app.use((req, res, next) => {req.name = 'router'req.on('end',() => {console.log('end')})next();
    });
    // 应用级别的中间件(局部中间件)
    app.get('/', myLogger, (req, res) => {console.log(req.name)res.send('Home page.')
    });
    app.listen(8081, function () {console.log("服务启动")
    })
    
    在这里插入图片描述
  2. 路由器级中间件
    绑定到express.Router()实例上的中间件,叫做路由级别的中间件。它的用法和应用级别中间件没有任何区别。只不过,应用级别中间件是绑定到 app实例上,路由级别中绚件摸定到router 实例上
    var express = require('express')
    var app = express()
    var router = express.Router()
    router.use(function (req, res, next) {console.log('Time:', Date.now());next()
    })
    app.use('/', router)
    app.listen(8081, function () {console.log("服务启动")
    })
    
    在这里插入图片描述
  3. 错误处理中间件
    错误处理中间件是专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题。
    格式:错误级别的中间件的 function 处理函数中,必须有 4 个形参,形参顺序从前到后,分别是(err,req,res,next)。
    注意:错误级别的中间件,必须注册在所有路由之后
    app.get('/', (req, res) => { // 1.路由throw new Error('服务器内部发生了错误');  // 1.1.抛出一个自定义的错误res.send('Home Page.');
    });
    app.use((err, req, res, next) => {    // 2.错误级别的中间件console.log('发生了错误:' + err.message);   // 2.1.在服务器打印错误消息res.send('Erroe!' + err.message); // 2.2.向客户端响应错误相关的内容
    });
    
  4. 内置中间件
    三个内置的中间件分别是
    express.static 是快速托管静态资源的内置中间件 例如:HTML文件、图片、CSS样式等(无兼容性)
    express.json是拿来解析json格式数据的
    express.urlencoded是拿来解析urlencoded格式数据的
    var express = require('express');
    var app = express();
    // 注意这是中间件 所以必须配置到路由之前
    app.use(express.json())
    app.use(express.urlencoded({extended : false}))
    app.listen(8081, function () {console.log("服务启动")
    })
    
  5. 第三方中间件
    非Express官方内置的,而是由第三方开发出来的中间件,叫做第三方中间件。在项目中,大家可以按需下载并配置第三方中间件,从而提高项目的开发效率。
    安装所需功能的 Node.js 模块,然后在应用程序级别或路由器级别将其加载到应用程序中。
    以cookie-parser为示例:
    $ npm install cookie-parser
    
    var express = require('express')
    var app = express()
    var cookieParser = require('cookie-parser')
    app.use(cookieParser())
    

3.自定义中间件

自定义中间件步骤:

  1. 定义中间件
  2. 监听req的data事件
  3. 监听req的end事件
  4. 使用querystring模块解析请求体数据
  5. 将解析出来的数据对象挂载为req.body
  6. 将自定义中间件封装为模块
    // myparse.js
    //1.1 导入内置模块
    const qs=require('querystring')
    //1.2 编写解析函数
    function myparse(req,res,next){//2.2 定义一个变量存储客户端字符串let str=''//2.1 对客户端请求数据的监听//注意是对客户端对象进行监听,而不是服务器req.on('data',(chunk)=>{str+=chunk})//2.4 进行发送数据结束的监听req.on('end',()=>{//倘若有响应,说明数据发送结束,我们已经拿到所有数据console.log(str)//4.2 利用内置模块的parser()进行数据解析const body=qs.parse(str)//4.3 进行数据对象的挂载req.body=bodyconsole.log(body)})//2.5 不要忘记需要调用next函数next()
    }
    //1.4 通过module.exports暴露
    module.exports = myparse
    
    // 使用
    var express = require('express');
    var app = express();
    // 2.1 导入自定义解析模块
    const myparse = require('./mybody-parse')
    app.use(myparse)
    app.get('/login', function (req, res) {console.log(req.body);res.end(req.body);
    })
    

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

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

相关文章

给UE5优化一丢丢编辑器性能

背后的原理 先看FActorIterator的定义 /*** Actor iterator* Note that when Playing In Editor, this will find actors only in CurrentWorld*/ class FActorIterator : public TActorIteratorBase<FActorIterator> {//..... }找到基类TActorIteratorBase /*** Temp…

小程序跳转到本页面并传参

const pages getCurrentPages(); const currentPage pages[pages.length - 1]; // 当前页面路由 const route currentPage.route; // 当前页面参数 const options currentPage.options;// 构建新的 URL 参数 const newOptions {...options,// newParam: newValue }; // 你…

【机器学习】支持向量机SVR、SVC分析简明教程

关于使用SVM进行回归分析的介绍很少&#xff0c;在这里&#xff0c;我们讨论一下SVR的理论知识&#xff0c;并对该方法有一个简明的理解。 1. SVC简单介绍 SVR全称是support vector regression&#xff0c;是SVM&#xff08;支持向量机support vector machine&#xff09;对回…

pytest+allure生成报告显示loading和404

pytestallure执行测试脚本后&#xff0c;通常会在电脑的磁盘上建立一个临时文件夹&#xff0c;里面存放allure测试报告&#xff0c;但是这个测试报告index.html文件单独去打开&#xff0c;却显示loading和404, 这个时候就要用一些办法来解决这个报告显示的问题了。 用命令产生…

分布式事务调研

目录 需求背景&#xff1a; 本地事务 分布式基本理论 1、CAP 定理 2、BASE理论 分布式事务方案 #2PC #1. 运行过程 #1.1 准备阶段 #1.2 提交阶段 #2. 存在的问题 #2.1 同步阻塞 #2.2 单点问题 #2.3 数据不一致 #2.4 太过保守 3PC #本地消息表 TCC TCC原理 …

鱼眼相机模型-MEI

参考文献&#xff1a; Single View Point Omnidirectional Camera Calibration from Planar Grids 1. 相机模型如下&#xff1a; // 相机坐标系下的点投影到畸变图像// 输入&#xff1a;相机坐标系点坐标cam 输出&#xff1a; 畸变图像素点坐标disPtvoid FisheyeCamAdapter::…

[GKCTF 2021]签到

[GKCTF 2021]签到 wireshark跟踪http流&#xff0c;基本编解码&#xff0c;倒叙&#xff0c;栅栏密码 找到cat /f14g 把包里返回的字符串先hex解码&#xff0c;再base64解码&#xff0c;看到一个时间是倒叙&#xff0c;不含flag 继续往下面翻&#xff0c;可以看到cat%2Ff14g%7…

【Linux】【字符设备驱动】深入解析

Linux字符设备驱动程序用于控制不支持随机访问的硬件设备&#xff0c;如串行端口、打印机、调制解调器等。这类设备通常以字符流的形式与用户空间程序进行交互。本节将深入探讨字符设备驱动的设计原理、实现细节及其与内核其他组件的交互。 1. 引言 字符设备驱动程序是Linux内…

【论文笔记】Tool Learning with Foundation Models 论文笔记

Tool Learning with Foundation Models 论文笔记 文章目录 Tool Learning with Foundation Models 论文笔记摘要背景&#xff1a;工作&#xff1a; 引言工具学习的发展本文工作&#xff08;大纲&目录&#xff09; 背景2.1 工具使用的认知起源2.2 工具分类&#xff1a;用户界…

电阻可靠性的内容

一、影响电阻可靠性的因素&#xff1a; 影响电阻可靠性的因素有温度系数、额定功率&#xff0c;最大工作电压、固有噪声和电压系数 &#xff08;一&#xff09;温度系数 电阻的温度系数表示当温度改变1摄氏度时&#xff0c;电阻阻值的相对变化&#xff0c;单位为ppm/℃.电阻温…

Redis等Spring Cache 框架 实现基于注解的缓存功能

Spring Cache 框架 实现基于注解的缓存功能 底层 基于代理技术 一旦进入方法就进入代理对象 如果redis里有就直接返回 不会走方法 如果缓存没有数据 则通过反射走方法。 概念 缓存 相当于之前的事务处理 同步更改 只是提供了一层抽象 底层可以切换不同的缓存实现 EHCach…

【Zookeeper】三,Zookeeper的安装与基本操作

文章目录 安装Zookeeper下载解压解压后的目录结构运行Zookeeper 基本操作 安装Zookeeper 下载 官网下载Zookeeper&#xff0c;会得到一个tar包&#xff0c;如&#xff1a;apache-zookeeper-3.8.4-bin.tar.gz 解压 tar -xvf apache-zookeeper-3.8.4-bin.tar.gz -C /usr/loca…

【Python TensorFlow】进阶指南(续篇四)

在前面的文章中&#xff0c;我们探讨了TensorFlow在实际应用中的多种高级技术和实践。本文将继续深入讨论一些更为专业的主题&#xff0c;包括模型压缩与量化、迁移学习、模型的动态调整与自适应训练策略、增强学习与深度强化学习&#xff0c;以及如何利用最新的硬件加速器&…

HASH256开源代码计算错误问题

计算量超500KB报错 OTA升级中可能会涉及到CRC、hash校验等算法&#xff0c;小编从网上抄到了HASH256的源码&#xff0c;拿来使用的时候却发现了一个问题&#xff0c;当源文件约大于500KB的时候会发现其计算出的hash值出现错误。 经过实际测试得知&#xff0c;当源文件大于约50…

【人工智能】Python常用库-TensorFlow常用方法教程

TensorFlow 是一个广泛应用的开源深度学习框架&#xff0c;支持多种机器学习任务&#xff0c;如深度学习、神经网络、强化学习等。以下是 TensorFlow 的详细教程&#xff0c;涵盖基础使用方法和示例代码。 1. 安装与导入 安装 TensorFlow&#xff1a; pip install tensorflow…

Spring Boot教程之十一:获取Request 请求 和 Put请求

如何在 Spring Boot 中获取Request Body&#xff1f; Java 语言是所有编程语言中最流行的语言之一。使用 Java 编程语言有几个优点&#xff0c;无论是出于安全目的还是构建大型分发项目。使用 Java 的优点之一是 Java 试图借助类、继承、多态等概念将语言中的每个概念与现实世…

uniapp实现组件竖版菜单

社区图片页面 scroll-view scroll-view | uni-app官网 (dcloud.net.cn) 可滚动视图区域。用于区域滚动。 需注意在webview渲染的页面中&#xff0c;区域滚动的性能不及页面滚动。 <template><view class"pics"><scroll-view class"left"…

Vue教程|搭建vue项目|Vue-CLI2.x 模板脚手架

一、项目构建环境准备 在构建Vue项目之前&#xff0c;需要搭建Node环境以及Vue-CLI脚手架&#xff0c;由于本篇文章为上一篇文章的补充&#xff0c;也是为了给大家分享更为完整的搭建vue项目方式&#xff0c;所以环境准备部分采用Vue教程&#xff5c;搭建vue项目&#xff5c;V…

前海湾地铁的腾通数码大厦背后的临时免费停车点探寻

临时免费停车点&#xff1a;前海湾地铁的腾通数码大厦背后的桂湾大街&#xff0c;目前看不仅整条桂湾大街停了​车&#xff0c;而且还有工地餐点。可能是这个区域还是半工地状态&#xff0c;故暂时还不会有​罚单的情况出现。 中建三局腾讯数码大厦项目部A栋 广东省深圳市南山…

遥感数据集:FTW全球农田边界和对应影像数据,约160万田块边界及7万多个样本

Fields of The World (FTW) 是一个面向农业田地边界实例分割的基准数据集&#xff0c;旨在推动机器学习模型的发展&#xff0c;满足全球农业监测对高精度、可扩展的田地边界数据的需求。该数据集由kerner-lab提供&#xff0c;于2024年8月28日发布&#xff0c;主要特征包括&…