web框架Express

web框架Express
LiSir1.认识express
- 简介:基于 Node.js 平台,快速、开放、极简的 Web 开发框架
- 类似于Node.js中的内置模块http模块,专门用来创建Web服务器。
安装
首先假定你已经安装了 Node.js,接下来为你的应用创建一个目录,然后进入此目录并将其作为当前工作目录。
1 | mkdir myapp |
通过 npm init 命令为你的应用创建一个 package.json 文件。 欲了解 package.json 是如何起作用的,请参考 Specifics of npm’s package.json handling.
1 | npm init |
此命令将要求你输入几个参数,例如此应用的名称和版本。 你可以直接按“回车”键接受大部分默认设置即可,下面这个除外:
1 | entry point: (index.js) |
键入 app.js 或者你所希望的名称,这是当前应用的入口文件。如果你希望采用默认的 index.js 文件名,只需按“回车”键即可。
接下来在 myapp 目录下安装 Express 并将其保存到依赖列表中。如下:
1 | npm install express --save |
如果只是临时安装 Express,不想将它添加到依赖列表中,可执行如下命令:
1 | npm install express --no-save |
使用
1 | //第一步:导入express模块 |
我们注意到,它的这个用法和node.js里面的http模块很相似,所以express相当于我们的http模块,但是express功能更强大。
获取请求路径中的参数
使用req.query()方法,该方法的默认值是一个空对象,当客户端携带了query参数(?age=20&name=zhangsan)时,可以获取到该参数
1 | app.get('/',function(req,res){ |
获取请求路径中的动态参数
语法:req.params()
通过该方法可以访问到请求路径中通过:匹配的动态参数
示例访问路径:localhost:8080/user/4
1 | app.get('/user/:id',function(req,res){ |
注意:id时动态参数
匹配多个动态参数的写法:user/:id/:name/:xxx...
2.基本路由
直接使用路由
路由是指确定应用程序如何响应客户端对特定端点的请求,该端点是一个 URI(或路径)和特定的 HTTP 请求方法(GET、POST 等)。
每个路由可以有一个或多个处理程序函数,这些函数在路由匹配时执行。
路由定义采用以下结构:
1 | app.METHOD(PATH, HANDLER) |
对参数的解释:
app是express的实例(对象)METHOD是一个小写HTTP请求方法(post,get,put,delete)PATH是所请求的资源在服务器上的路径HANDLER是路由匹配时执行的函数。
举个例子
在主页上响应’Hello World!’
1 | app.get('/',function(req,res){ |
响应 POST请求在根路径/
1 | app.post('/',function(req,res){ |
响应一个PUT请求在路径/user
1 | app.put('/user',function(req,res){ |
注意:
- 按照定义的先后顺序进行匹配
- 请求类型和请求URL同时匹配成功,才会调用对应的处理函数
模块化路由
express不建议直接将路由挂载到app上,推荐把路由抽离为单独的模块
模块化路由步骤如下
- 创建路由模块对应的.js文件
- 调用express.Router()函数创建路由对象
- 向路由对象上挂载具体路由
- 使用module.exports共享路由
- 使用app.use()函数注册路由模块
1 | //引入express模块 |
注册路由步骤:
- 导入路由模块
- 注册路由模块
这里我们用上面自定义的模块路由演示
1 | //导入路由自定义模块 |
为路由模块添加前缀
类似于托管静态资源,为静态资源添加前缀,给路由模块添加前缀的如下
1 | //导入路由自定义模块 |
当我们为路由模块添加了前缀时,在访问时,路径变成了/api/xxx
3.托管静态资源
托管资源
为了提供诸如图像、CSS 文件和 JavaScript 文件之类的静态文件,请使用 Express 中的 express.static 内置中间件函数。
此函数特征如下:
1 | express.static(root, [options]) |
例如,通过如下代码就可以将 public 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了:
1 | app.use(express.static('public')) |
现在,你就可以访问 public 目录中的所有文件了:
1 | http://localhost:3000/images/kitten.jpg |
Express 在静态目录查找文件,因此,存放静态文件的目录名不会出现在 URL 中。
托管多个静态资源
如果要使用多个静态资源目录,请多次调用 express.static 中间件函数:
1 | app.use(express.static('public')) |
访问静态资源文件时,express.static 中间件函数会根据目录的添加顺序查找所需的文件。
为托管的静态资源添加前缀
语法:
1 | app.use('/static', express.static('public')) |
现在,你就可以通过带有 /static 前缀地址来访问 public 目录中的文件了。
1 | http://localhost:3000/static/images/kitten.jpg |
4.nodemon工具
nodemon会在我们的代码修改时,自动的重启服务器,极大地提高了开发效率
安装
1 | npm i nodemon -g |
使用
1 | #安装nodemon后通过下面命令启动项目即可 |
5.中间件
简介
Express 是一个路由和中间件 Web 框架,它本身具有最少的功能:Express 应用程序本质上是一系列中间件函数调用。
简单理解
中间件函数是可以访问请求对象 (req)、响应对象 (res) 以及应用程序请求-响应周期中的下一个中间件函数的函数。下一个中间件函数通常由名为next的变量表示。
中间件函数可以执行以下任务:
执行任何代码。
对请求和响应对象进行更改。
结束请求-响应周期。
调用堆栈中的下一个中间件函数。
如果当前中间件函数未结束请求-响应周期,则必须调用 next() 将控制权传递给下一个中间件函数。否则,请求将悬而未决。
您可以使用可选的挂载路径加载应用程序级和路由器级中间件。您还可以将一系列中间件函数一起加载,从而在挂载点创建中间件系统的子堆栈。
中间件的调用流程
当一个请求达到Express服务器之后。可以连续调用多个中间件,从而对这个请求进行预处理
中间件的执行顺序和我们定义的顺序一样
中间件处理函数
Express的中间件,本质上就是一个function处理函数,他的格式如下
在中间件函数中,必须包含next参数,但是在路由处理函数的参数中只有req和res
next函数
中间件中的流转通过next函数实现,用于多个中间件连续调用。非常重要
中间件函数例子
以下是一个简单的“Hello World” Express 应用程序示例。名为 myLogger 的函数用于打印简单的日志消息。
准备web服务器
1 | var express = require('express') |
定义中间件函数 myLogger
下面是一个名为“myLogger”的中间件函数的简单示例。当应用程序的请求通过该函数时,该函数只会打印“LOGGED”。中间件函数被分配给一个名为 myLogger 的变量。
1 | var myLogger = function (req, res, next) { |
注意:请注意上面对 next() 的调用。调用此函数会调用应用中的下一个中间件函数。next() 函数不是 Node.js 或 Express API 的一部分,而是传递给中间件函数的第三个参数。next() 函数可以命名为任意名称,但按照惯例,它始终命名为“next”。为避免混淆,请始终使用此惯例。
要加载中间件函数,请调用 app.use(),并指定中间件函数。例如,以下代码在路由挂载到根路径 (/) 之前加载 myLogger 中间件函数。
1 | var express = require('express') |
每次应用程序收到请求时,它都会将消息“LOGGED”打印到终端。
中间件加载的顺序很重要:首先加载的中间件函数也会首先执行。
如果 myLogger 在路由到根路径之后加载,则请求永远不会到达它,并且应用程序不会打印“LOGGED”,因为根路径的路由处理程序会终止请求-响应循环。
中间件函数 myLogger 只是打印一条消息,然后通过调用 next() 函数将请求传递给堆栈中的下一个中间件函数。
中间件的作用
多个中间件之间,共享同一份req和res,基于特性,我们可以再上一个中间件中,统一为req或res对象添加自定义的属性或方法,供下一个中间件或路由进行使用。
局部中间件
我们知道用app.use()方法挂载的是全局中间件,下面我们介绍一下局部中间件
1 | const express = require('express') |
当我们**没有使用app.use()**定义中间件时,那他就是一个局部中间件。使用局部中间件时,想用到那个路由,就在请求方法列表中加入该中间件的名称,比如上面,中间件只对/user路由生效,而下面的不会生效。
当我们使用多个局部中间件时,只需要把多个局部中间件用,隔开即可。或者用数组的形式也可以。
中间件的注意事项
- 一定要在路由之前注册中间件
- 客户端发送来的请求,可以调用多个中间件进行处理
- 执行完中间件的业务代码之后,不要忘记调用next()函数
- 多个中间件之间,共享req(请求对象)和res(响应对象)
6.中间件的分类
Express 应用程序可以使用以下类型的中间件:
- 应用程序级中间件
- 路由器级中间件
- 错误处理中间件
- 内置中间件
- 第三方中间件
应用程序级中间件
使用 app.use() 和 app.METHOD() 函数将应用程序级中间件绑定到 app 对象的实例,其中 METHOD 是中间件函数处理的请求的 HTTP 方法(例如 GET、PUT 或 POST),以小写形式表示。
此示例显示了一个没有挂载路径的中间件函数。每次应用程序收到请求时都会执行该函数。
1 | var express = require('express') |
路由器级中间件
路由器级中间件的工作方式与应用程序级中间件相同,只是它绑定到 express.Router() 的实例。
1 | var express = require('express') |
错误处理中间件
错误处理中间件始终需要四个参数。您必须提供四个参数来将其标识为错误处理中间件函数。即使您不需要使用下一个对象,也必须指定它以维护签名。否则,下一个对象将被解释为常规中间件,并且无法处理错误。
定义错误处理中间件函数的方式与其他中间件函数相同,只是使用四个参数而不是三个,具体来说是使用 (err, req, res, next):
1 | app.use(function (err, req, res, next) { |
内置中间件
Express 具有以下内置中间件功能:
express.static 提供静态资产,例如 HTML 文件、图像等。
express.json 使用 JSON 负载解析传入请求。注意:适用于 Express 4.16.0+
1 | //使用express.json中间件,将数据挂载req.body属性上 |
express.urlencoded 使用 URL 编码负载解析传入请求(application/x-www-form-urlencoded格式数据)。注意:适用于 Express 4.16.0+
1 | //使用express.urlencoded中间件,将数据挂载req.body属性上 |
第三方中间件
使用第三方中间件为 Express 应用添加功能。
安装所需功能的 Node.js 模块,然后在应用程序级别或路由器级别将其加载到您的应用中。
以下示例说明了如何安装和加载 cookie 解析中间件函数 cookie-parser。
1 | npm install cookie-parser |
1 | var express = require('express') |
7.自定义中间件
1.实现步骤
2.监听req的data事件
1 | app.use((req,res,next)=>{ |
3.监听req的end事件
1 | app.use((req,res,next)=>{ |
4.使用querystring模块解析请求数据
1 | const express = require('express') |
5.将解析出来的数据对象挂载到req的body属性上
1 | req.on('end',function(){ |
6.将自定义中间件封装为模块
新建一个custom-body-parser.js文件
写入以下内容
1 | //搭配node.js中的querystring模块 |
1 | //在需要用解析功能的js文件中导入js文件即可 |
完整代码
1 | const express = require('express') |
8.基于express写接口
写一个自定义路由模块
1 | const express = require('express') |
导入模块
1 | //导入路由模块 |
上面这个就是get接口。
下面来举例post接口
1 | //解析post请求的数据,详见目录内置中间件 |









