中间件(需要使用express)

本质上是一个函数,包含三个参数

requestresponsenext

作用

  • 执行任何代码
  • 修改请求和响应对象
  • 终结请求-响应循环(让一次请求得到响应)
  • 调用堆栈中的下一个中间件或者路由

分类

  • 应用级中间件(全局)(过滤非法的请求,例如防盗链)

  • 第三方中间件(通过npm下载的中间件)

  • 内置中间件(框架内部内置的中间件)

  • 路由中间件(Router)

应用中间件

第一种使用全局中间件

所有的请求都会进入该中间件

const express = require('express');const app = express();// 应用级中间件
app.use((req, res, next) => {res.send('这是中间件的响应');
});// 根路由
app.get('/', (req, res) => {res.send('这是根路由响应');
});app.get('/1', (req, res) => {res.send('这是一级路由');
});app.get('/1/2', (req, res) => {res.send('这是二级路由');
});app.listen(8080, (err) => {if (!err) {console.log('ok');} else {console.log(err);}
});
  • 访问根路由

  • 访问一级路由

  • 访问二级路由

访问的时候我们发现,无论是请求的哪个路由,都是返回应用级中间件的响应,且后序路由不在执行,当我们调用next后,便可以访问到目标路由。

将应用级中间件写在请求的任意位置,请求会依照代码顺序执行,若是执行到该中间件,那么它科能会影响到下一级中间件(若在一级与二级路由之间设置一个应用级中间件且无next,那么智能响应一级路由之前的路由,二级路由是无法访问到的)

在express中,定义路由和中间件的时候,根据定义顺序,将每一个中间件或者路由放在一个类似于数组的容器中,当请求过来的时候,依次从容器中取出中间件和路由进行匹配,如果匹配你成功,则交由该中间件或者路由处理,如果如果全局中间件定义在最开始的位置,那么所有的请求都会进入该中间件。

对于浏览器来说,每一次请求只会有一个请求对象,和一个响应对象,后续路由使用的req和res都是同一个req,res对象

注意: 在中间件中无法在next调用之前使用返回响应

函数式中间件的定义方式

const express = require('express');const app = express();// 函数式应用级中间件
function middleware(request, response, next){// 应用级中间件app.use((req, res, next) => {res.send('这是中间件的响应');});
}// 根路由
app.get('/', (req, res) => {res.send('这是根路由响应');
});// 使用应用中间件
app.get('/1', middleware, (req, res) => {res.send('这是一级路由');
});app.get('/1/2', (req, res) => {res.send('这是二级路由');
});app.listen(8080, (err) => {if (!err) {console.log('ok');} else {console.log(err);}
});

区别:更加灵活,可以在需要的地方使用(依据请求的路径选择使用中间件),第一种方式更适合所有请求需要做某种操作时使用。

使用方式:传入到路由的第二个参数的位置。


第三方中间件

通过npm和yarn下载的中间件

内置中间件

express内置有一些中间件

静态文件

可以通过express.staict设置静态文件

app.use(express.staict(__dirname + '/public'));
//  将当前文件夹下的public文件夹设置为静态访问

注意:访问静态文件夹内的文件需要添加上后缀

路由器

express框架中引入了路由器的概念,使用了路由器可以使代码结构功能更加清晰,便于维护

server文件

/*
* 基础页面
* */const express = require('express');const app = express();// 解析post传递的参数
app.use(express.urlencoded({extended: false}));
// 解析json
app.use(express.json());// 加载路由器
const {router} = require('./Router/router');// 使用路由器中间件
app.use(router());app.listen(3300, (err) => {if (err) {console.log(err);} else {console.log('ok');}
});

router

/*
* 路由器模块
* */// 加载路由方法
const {Router} = require('express');// 创建路由器实例
const router = Router();// 加载 fs文件模块 解析绝对路径方法
const {moudule:{fs, resolve}} = require('../module/module');router.get('/', (req, res) => {let path = resolve(__dirname, '../public/index.html');let html = '';let rs = fs.createReadStream(path, {highWaterMark: 10 * 1024 * 1024});rs.on('open', () => {console.log('可读开启');});rs.on('close', () => {console.log('可读关闭');res.send(html);});rs.on('data', (data) => {html += data;});});router.post('/login', (req, res) => {let {body: {uname, pwd}} = req;if (pwd === '0059') {res.send('你好' + uname);// res.redirect(302, '/');} else {res.send('password is error');}});// 暴露路由器对象
module.exports.router = function () {return router;
}

module

/*
* module 核心模块
* */// 文件系统
const fs = require('fs');// path模块
const {resolve} = require('path');// 暴露
module.exports.moudule = {fs,resolve
};

public

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>input {width: 200px;height: 30px;outline: 0;font-size: 18px;border: 1px solid #ccc;border-radius: 4px;}input:hover {box-shadow: 0 0 1px 1px aqua;}button {padding: 10px 20px;outline: 0;color: #666;font-weight: 700;font-size: 18px;cursor: pointer;border-radius: 10px;}div {margin-top: 30px;}</style>
</head>
<body>
<h1>服务器接收Get和post请求测试</h1><!--提交信息-->
<input type="text" name="uname" placeholder="请输入姓名"><br><br>
<input type="password" name="pwd" id="" placeholder="请输入密码"><br><br>
<button>提交</button>
<div></div>
<script>// 获取元素let btn = document.querySelector('button'),input = document.querySelectorAll('input'),div = document.querySelector('div'),bool = true;btn.addEventListener('click', () => {if (bool) {bool = false;let obj = {uname: input[0].value, pwd: input[1].value};let xml = new XMLHttpRequest();xml.timeout = 1200;xml.open('POST', 'http://localHost:3300/login', true);// 设置解析json格式的请求头xml.setRequestHeader("Content-type", "application/json; charset=utf-8");xml.addEventListener('readystatechange', () => {// 4 表示接收到全部响应数据// 3 表示接收到部分响应数据(响应中)// 2 表示已初始化(open调用)但是没有发送请求// 1 表示已初始化(open调用)但是没有调用send()// 0 表示未初始化(open未调用)try {if (xml.readyState === 4) {// 表示接收到全部响应数据了if (xml.status >= 200 && xml.status < 300) {div.innerHTML = xml.responseText;bool = true;}}} catch (error) {alert('出现未知错误!' + error);}});xml.send(JSON.stringify(obj));}});
</script>
</body>
</html>

Node中间件和路由器相关推荐

  1. node中间件是什么意思?

    node中间件是什么意思? 2020-09-11 16:11:17分类:常见问题 / Node.js答疑阅读(1757)评论(0) 中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不 ...

  2. node中间件有哪些类型?

    node中间件就是封装在程序中处理http请求的功能.node中间件是在管道中执行.中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯. 中间件为主要的逻辑业务所服务,可分为:应用级中 ...

  3. vue+node全栈移动商城【10】注册页面传值到node中间件

    上一节咱们已经实现了注册页面的基本结构,在这一节,咱们把注册页面的值,传入到nodeJs的中间件中,为接下来的保存用户注册信息做好准备. 我们已经在vant的组件输入框上,以v-model的方式双向绑 ...

  4. node中间件mysql_nodejs 中使用mysql数据有没有类似 mongoose 的中间件?

    在nodejs 操作mysql 时 ,我遇到了这样的问题: 一次http请求需要执行多个query,所有为了减少callback 我使用async中的waterfall函数 将query分函数来写,并 ...

  5. node中间件KOA函数

    const Koa = require('koa'); const app = new Koa() //应用程序对象 中间件 // 发送HTTP KOA 接手HTTP //中间件(其实就是 函数) f ...

  6. react 路由重定向_如何测试与测试库的路由器重定向React

    react 路由重定向 React testing-library is very convenient to test React components rendering from props, ...

  7. 《敬告青年》陈独秀《新青年》杂志发刊词

    敬告青年 "自主的而非奴隶的:等一人也,各有自主之权. 进步的而非保守的:人生如逆水行舟,不进则退. 进取的而非退隐的:夫生存竞争,势所不免,一息尚存,即无守退安隐之余地.排万难而前行,乃人 ...

  8. vue路由登录拦截器_Vue路由器

    vue路由登录拦截器 介绍 (Introduction) In a JavaScript web application, a router is the part that syncs the cu ...

  9. 网关和路由器的区别是什么?

    在使用Windows系统的PC机上配置Internet协议(TCP/IP)属性时,"默认网关"是指路由器(Router)还是网关(Gateway)? 公路旅行/滑雪/摄影/立志成为 ...

最新文章

  1. umi搭建react+antd项目(六)父子组件通讯
  2. 截断骨干用于检测,YOLO-ReT开源:边缘GPU设备上的高性能检测器
  3. android 键盘 能复制,android – 从EditText中禁用软键盘,但仍允许复制/粘贴?
  4. larval+mysql+不等于_MySQL学习日记(19)比较运算符
  5. html5 xml文本编辑,简介XML文档的阅读与编辑
  6. python3socket非阻塞在linux里无效_Linux下socket设置为非阻塞方式和fcntl系统调用
  7. 计算机 信息安全常识
  8. C语言:ASCII码对照表
  9. 粉红噪音测试软件,爱卡音响测试(59) Levante和B&W音响
  10. 在Kali中使用Ettercap进行ARP欺骗
  11. 关于sql查询分析器无法登录的问题
  12. c++ 调用meshlab程序慢_从Meshlab学架构
  13. 第六天、用户、组、权限、grep
  14. 计算机软件著作权 评审,软件著作权在评职称过程中有用吗
  15. 钢铁侠材质制作——2、线条轮廓部分的制作
  16. 12.2总结(纵使结局不如意,放弃实属下下签。)
  17. 银河麒麟桌面操作系统V10日常使用说明
  18. ubuntu20.04 LTS 更换国内163源、阿里源、清华源、中科大源
  19. matlab的仿真实验报告答案,模糊控制MALTAB系统仿真实验报告
  20. BMP格式补充(16bbp 32bbp 4字节对齐 pixel data存放顺序)

热门文章

  1. 【数据分析案例】使用机器学习做游戏留存数据挖掘的一种尝试
  2. Muli3D 3 qQuaternionRotationMatrix 函数 (矩阵转四元数)
  3. STM32超低功耗入门之停止模式
  4. Linux-centos7-防火墙
  5. PDF文档搜索工具:PDF Search Mac版
  6. 饿死也别进外包公司!说好不加班才入职,结果连续工作10小时,提出辞职后,外包公司竟以时间短为理由拒绝给工资!...
  7. 简单明了的阐述SVM支持向量机以及做法步骤
  8. RAID基础(附RAID10搭建)
  9. Bigdecimal BigDeciamal元转换为万元,转换为百分数,字符串与数值互转,整数/浮点数转换为BigDeciamal 获取当前年月日时分秒 百分比数据保留两位小数
  10. ABP VNext学习日记5