概念: 中间件(Middleware)本质上是一个函数,可以访问request,response,next
作用:使用函数封装公共操作,简化代码
使用:当一个请求到达 Express 的服务器之后,可以连续调用多个中间件,从而对这次请求进行预处理。
类型:全局中间件和路由中间件
全局中间件:每一个请求到达服务端之后,都会执行全局中间件函数.
每一次路由的请求到达服务端之后,所有的路由都要执行中间件,无论是否存在该路由规则,中间件都会执行。
【注】:中间件其实就是一个函数(箭头函数/匿名函数),函数是需要传递三个(request,response,next)
【注】:中间件不仅要声明, 还要use方法来调用中间件。
【注】:调用next函数表示这个中间件处理完毕之后,要交给下一个中间件或者路由规则去处理,最终next方法会指向路由规则的响应体的回调函数。
//方式一:先声明再使用
let middleWare = (req,res,next) => {
console.log('我是全局中间件');
next();
})
app.use(middleWare);
//方式二:边声明边使用
app.use(function(req,res,next) => {
console.log('我是全局中间件');
next();
})
针对于某些路由,而非全部路由规则,设置中间件,路由中间件不需要使用use方法调用
let oneRouterMiddleWare = (request,response,next) => {
let now = new Date();
console.log(now.toLocaleString());
console.log('第一个路由中间件');
next();
}
let twoRouterMiddleWare = (request,response,next) => {
console.log('第二个路由中间件');
next();
}
//方式一
app.get('/usercenter',[oneRouterMiddleWare,twoRouterMiddleWare],(request,response) => {
response.end('用户中心');
})
//访问register页面时,需要先走中间件,然后再去响应体的回调函数
//方式二
app.get('/usercenter',oneRouterMiddleWare,twoRouterMiddleWare,(request,response) => {
response.end('用户中心');
})
主要的目的是为了更好地分类管理路由,子路由文件其实就是按照对应的功能划分路由
server.js文件:
//1、导包
const express = require('express');
//导入文件模块
//这句话的含义:
//require('./routes/userRoutes')里面导出了一个模块对象,
//在server.js文件里面也需要userRoutes文件导出的对象内容,那么咱们需要变量/常量来接收它
//require在执行导包时,首先读取以.js结尾的文件,故如果文件后缀为.js,那么可以省略不写
const userRoutes = require('./routes/userRoutes');
const orderRoutes = require('./routes/orderRoutes')
//2、创建服务对象
const app = express();
//通过app对象进行使用子模块路由对象
app.use(userRoutes, orderRoutes);
//3、建立路由规则
app.get('/', (request, response) => {
response.send('home');
});
//4、设置监听端口
app.listen(80, () => {
console.log('80端口正在运行中...')
})
userRoutes.js文件:
//1、导包
const express = require('express');
//2、创建 子路由对象 app=express()总路由对象
const userRoutes = express.Router();
//2、利用子路由对象 创建子模块路由规则
userRoutes.get('/login' ,(req,res) => {
res.send('用户登录');
})
//4、暴露模块/模块导出
//modules:模块(一个小的功能,一个Js文件就是一个功能模块)
//exports:导出/出口===》暴露
//当前文件所创建的变量/常量作用域:归当前文件所有
module.exports = userRoutes;
如果请求方式为get:
GET没有请求体,可以使用express中内置api:
request.query:返回一个对象,请求字符串
request.params:返回一个对象,url中占位符如果请求方式是post:
express中没有内置获取表单post请求体的方法,需要借助第三方模块—body-parser
app.use(bodyParser.urlencoded({extended:false}))
【注】:客户端通过post表单提交给服务端数据,服务端需要使用body-parser中间件,解析请求体内容
const express = require('express');
//Step1:导包
const bodyParser = require('body-parser');
const app = express();
//Step2:解析请求体中的内容
//使用body-parser中间件
app.use(bodyParser.urlencoded({extended:false}));
//请求头中添加:Content-Type:application/x-www-form-urlencoded
//Step3:获取表单中请求体的内容(post方法)
//之前:用data事件和end事件获取post提交方法中请求体的内容
//现在:request.body ===> 对象
app.post('/login',(request,response) => {
console.log(request.body);//{ username: 'Evelyn', userpass: '1111' }
console.log(request.body.username);//Evelyn
console.log(request.body.userpass);//1111
response.send('登录页面');
}
//Step4:设置监听端口
app.listen(80,() => {});
静态资源放在public目录,公共资源文件都放在public文件夹下。
静态资源:长时间不发生改变的资源,称之为静态资源,如:css、js、img、font、html。
【注】:直接读出文件内容,之前是使用fs模块的读文件。
【注】:静态资源,在url地址栏访问时,就不用输入public目录了,直接输入后边的。
//引入express框架
const express = require('express');
//创建服务对象
const app = express();
//静态资源中间件的设置,将当前文件夹下的public目录作为网站的根目录
//public目录中都是一些静态资源
app.use(express.static('./public'));
//如果访问的内容经常变化,还是需要设置路由
//但是,在这里有一个问题,如果public目录下有index.html文件,单独也有index.html的路由,
//则谁书写在前,优先执行谁
app.get('/index.html',(request,response)=>{
respsonse.send('首页');
});
//监听端口
app.listen(80,()=>{
console.log('80端口启动....');
});
动静分离:服务端数据和html页面结构,模板引擎是为了使用户界面和业务数据分离而产生
<%= EJS语法 %>
//1、导包
const ejs = require('ejs');
//ejs主要的作用是为了让页面结构和实际动态数据相分离
//2.定义模拟数据
//现在是自己定义来模拟
//后期是通过Ajax访问服务端连带数据库做真实的数据响应
let arr = ['a','b','c'];
//3.使用ejs渲染数据
//渲染(包含HTML结果以及动态数据)
//传两个参数:ejs.render(<%=输出内容%>,{键名:键值});
//<%= ... %>是ejs解析内容的标记,作用是输出当前表达式的执行结构
ejs.render('<%= arr.join(",")%>',{arr:arr});
//需要注意的是,单双引号交替
//返回的是一个字符串内容(打印)
//Step1:初始化,安装ejs包
//Step2:配置模板引擎的语法为ejs,固定写法
//view engine:模板引擎
app.set('view engine','ejs');
//Step3:配置模板的存放目录(views视图文件夹的路径)
//可以是绝对路径也可以是相对路径
//ejs文件存放在views目录下
app.set('views','./view')
//app.set('views' , __dirname + '/views');
//Step4:使用模板
app.get('/list',() => {
let arr = [];
response.render('users',{arr});
//render方法中的第一个参数是views目录中的文件名前缀(users.ejs)
//键名就是模板中的变量名{arr:arr}
//键值就是实际使用的数据
})