重识express再学一遍

一. express 简介

express官网https://www.expressjs.com.cn/
基于Node.js平台,快速、开放、极简的Web开发框架
安装:

npm install express --save

使用express可以方便快速的创建web网站的服务器或者api接口的服务器

1. 使用express创建基本的服务器

// 1.导入express
const express = require('express')
// 2.创建web服务器
const app = express()
// 3.启动服务器
app.listen(80, ()=>{
    console.log('express服务器启动成功,http://127.0.0.1:80')
})

2. 监听get/post请求

// 参数1:客户端请求的url地址
// 参数2:请求对应的处理函数 (req请求对象,res响应对象)
app.get('请求url', function(req, res) {'处理函数'})
app.post('请求url', function(req, res) {'处理函数'})

3. 把内容响应给客户端

通过res.send()方法把内容响应给客户端

app.get('/user', (req, res) => {
	//向客户端发送JSON对象
	res.send({name: 'zhangsan', age: '18'})
})

示例:

// 1.导入express
const express = require("express");
// 2.创建web服务器
const app = express();

// 4. 监听客户端的 GET 和 POST 请求,并向客户端响应具体的内容
app.get("/user", (req, res) => {
  // 调用 express 提供的 res.send() 方法,向客户端响应一个 JSON 对象
  res.send({ name: "zs", age: 20, gender: "男" });
});
app.post("/user", (req, res) => {
  // 调用 express 提供的 res.send() 方法,向客户端响应一个 文本字符串
  res.send("请求成功");
});

// 3.启动服务器
app.listen(80, () => {
  console.log("express服务器启动成功,http://127.0.0.1:80");
});

此时启动一下该服务器:

node 文件名.js

当你看到这一句话时代表你的服务器创建成功了
在这里插入图片描述

接着我们可以使用postman测试一下这两个接口
get
在这里插入图片描述
post
在这里插入图片描述

4. 通过req.query可以获取到客户端发过来的查询参数

// 1. 导入 express
const express = require('express')
// 2. 创建 web 服务器
const app = express()

app.get('/', (req, res) => {
  // 通过 req.query 可以获取到客户端发送过来的 查询参数
  // 注意:默认情况下,req.query 是一个空对象
  console.log(req.query)
  res.send(req.query)
})

// 3. 启动 web 服务器
app.listen(80, () => {
  console.log('express server running at http://127.0.0.1')
})

运行然后去postman测试
在这里插入图片描述
可以看到此处响应了一个空对象,可以证明req.query默认就是一个空对象

接着我们携带一些参数发送请求:
在这里插入图片描述

5. 获取url中的动态参数

通过req.params对象,可以访问到url中通过:匹配到的动态参数

// 1.导入express
const express = require("express");
// 2.创建web服务器
const app = express();

// 注意:这里的 :id 是一个动态的参数
app.get("/user/:ids/:username", (req, res) => {
  // req.params 是动态匹配到的 URL 参数,默认也是一个空对象
  console.log(req.params);
  res.send(req.params);
});

// 3.启动服务器
app.listen(80, () => {
  console.log("express服务器启动成功,http://127.0.0.1:80");
});

在这里插入图片描述

6. 托管静态资源

express.static()
通过express.static可以创建一个静态资源服务器,如下代码,就可以将public目录下的图片、css文件、javascript文件对外开放

app.use(express.static(‘public’))

现在就可以访问public目录下的所有文件了

http://localhost:80/images/bg.jpg
http://localhost:80/css/stylse.css

挂载路径前缀

app.use(‘/files’, express.static(‘files’))

挂载前缀之后我们要访问的静态资源路径就变为了如下:
http://localhost:80/files/index.html

7. nodemon

nodemon是一个工具,在我们编写node项目时,如果修改了代码,就得频繁的手动关闭重启项目,nodemon它可以监听项目的文件变动,然后自动帮我们重启项目,极大的方便了我们的开发和调试。

启动命令

nodemon 监听文件名.js

二. express 路由

1.概念

路由就是映射关系,在express中路由指的是客户端的请求与服务器之间的映射关系。
express中路由分3部分组成,分别是请求的类型、请求的url、处理函数,格式如下:

app.method(path, handler)

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

2.模块化路由

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

  1. 创建路由对应的js文件
  2. 调用express.Router()函数创建路由对象
  3. 向路由对象上挂载具体的路由
  4. 使用module.exports向外共享路由对象
  5. 使用app.use()函数注册路由模块
    示例如下:
// 这是路由模块 router.js
// 1. 导入 express
const express = require('express')
// 2. 创建路由对象
const router = express.Router()

// 3. 挂载具体的路由
router.get('/user/list', (req, res) => {
  res.send('Get user list.')
})
router.post('/user/add', (req, res) => {
  res.send('Add new user.')
})

// 4. 向外导出路由对象
module.exports = router

在app.js中注册使用

const express = require('express')
const app = express()

// app.use('/files', express.static('./files'))

// 1. 导入路由模块
const router = require('./router')
// 2. 注册路由模块
app.use('/api', router)

// 注意: app.use() 函数的作用,就是来注册全局中间件

app.listen(80, () => {
  console.log('http://127.0.0.1')
})

三. 中间件

1. 概念

中间件,特指业务流程的中间处理环节
express中间件,本质上就是一个function处理函数,Express中间件的格式如下:

app.get('/', function(req, res, next) => {
	next()
})

中间件函数的形参列表中,必须包含next参数,而路由处理函数中只包含req和res。
next()函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件或路由。

2.全局生效的中间件

客户端发起的任何请求,到达服务器之后,都会触发的中间件,叫做全局生效的中间件,通过调用app.use(中间件函数),即可定义一个全局生效的中间件,如下:

const express = require('express')
const app = express()

// // 定义一个最简单的中间件函数
// const mw = function (req, res, next) {
//   console.log('这是最简单的中间件函数')
//   // 把流转关系,转交给下一个中间件或路由
//   next()
// }

// // 将 mw 注册为全局生效的中间件
// app.use(mw)

// 这是定义全局中间件的简化形式
app.use((req, res, next) => {
  console.log('这是最简单的中间件函数')
  next()
})

app.get('/', (req, res) => {
  console.log('调用了 / 这个路由')
  res.send('Home page.')
})
app.get('/user', (req, res) => {
  console.log('调用了 /user 这个路由')
  res.send('User page.')
})

app.listen(80, () => {
  console.log('http://127.0.0.1')
})

接着我们启动这个服务,用postman调用接口看看我们定义的中间件是否生效
在这里插入图片描述
在这里插入图片描述
如上图,接口调用成功,控制台先打印了中间的内容,在打印接口的内容,说明我们定义的中间件生效了。

3.中间件的作用

多个中间件之间共享同一份reqres,基于这样的特性,我们可以在上游的中间件中,统一为reqres对象添加自定义的属性和方法,供下面的中间件或者路由使用。

const express = require('express')
const app = express()

// 这是定义全局中间件的简化形式
app.use((req, res, next) => {
  // 获取到请求到达服务器的时间
  const time = Date.now()
  // 为 req 对象,挂载自定义属性,从而把时间共享给后面的所有路由
  req.startTime = time
  next()
})

app.get('/', (req, res) => {
  res.send('Home page.' + req.startTime)
})
app.get('/user', (req, res) => {
  res.send('User page.' + req.startTime)
})

app.listen(80, () => {
  console.log('http://127.0.0.1')
})

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

4.定义多个全局中间件

const express = require('express')
const app = express()

// 定义第一个全局中间件
app.use((req, res, next) => {
  console.log('调用了第1个全局中间件')
  next()
})
// 定义第二个全局中间件
app.use((req, res, next) => {
  console.log('调用了第2个全局中间件')
  next()
})

// 定义一个路由
app.get('/user', (req, res) => {
  res.send('User page.')
})

app.listen(80, () => {
  console.log('http://127.0.0.1')
})

在这里插入图片描述
在这里插入图片描述
如上图所示,我们在调用接口之后,控制台依次输出了全局中间件内容。

5.局部生效的中间件

不使用app.use定义的中间件,就叫做局部生效的中间件。如下示例:

// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()

// 1. 定义中间件函数
const mw1 = (req, res, next) => {
  console.log('调用了局部生效的中间件')
  next()
}

// 2. 创建路由
app.get('/', mw1, (req, res) => {
  res.send('Home page.')
})
app.get('/user', (req, res) => {
  res.send('User page.')
})

// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(80, function () {
  console.log('Express server running at http://127.0.0.1')
})

在这里插入图片描述
在这里插入图片描述
如上图我们调用’/user’接口时,控制台没有打印中间件中的内容
在这里插入图片描述
在这里插入图片描述
当我们调用‘/’时,控制台打印了中间的内容,说明局部的中间件生效了。

6.调用多个局部生效的中间件

// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()

// 1. 定义中间件函数
const mw1 = (req, res, next) => {
  console.log('调用了第一个局部生效的中间件')
  next()
}

const mw2 = (req, res, next) => {
  console.log('调用了第二个局部生效的中间件')
  next()
}

// 2. 创建路由
app.get('/', [mw1, mw2], (req, res) => {
  res.send('Home page.')
})
app.get('/user', (req, res) => {
  res.send('User page.')
})

// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(80, function () {
  console.log('Express server running at http://127.0.0.1')
})

7.中间件的分类

  1. 应用级别的中间件:绑定到app实例上的中间件如:app.use(), app.get()
  2. 路由级别的中间件:绑定到express.Router()实例上的中间件
  3. 错误级别的中间件
  4. express内置的中间件
  5. 第三方的中间件

8.错误级别中间件

作用:专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题。
注意:错误级别中间件要放在路由之后

// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()

// 1. 定义路由
app.get('/', (req, res) => {
  // 1.1 人为的制造错误
  throw new Error('服务器内部发生了错误!')
  res.send('Home page.')
})

// 2. 定义错误级别的中间件,捕获整个项目的异常错误,从而防止程序的崩溃
app.use((err, req, res, next) => {
  console.log('发生了错误!' + err.message)
  res.send('Error:' + err.message)
})

// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(80, function () {
  console.log('Express server running at http://127.0.0.1')
})

在这里插入图片描述

9.常用的内置中间件

  1. express.static() 快速托管静态资源
  2. express.json() 解析json格式请求体数据
  3. express.urlencoded解析URL-encoded格式的请求体数据。
// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()

// 注意:除了错误级别的中间件,其他的中间件,必须在路由之前进行配置
// 通过 express.json() 这个中间件,解析表单中的 JSON 格式的数据
app.use(express.json())
// 通过 express.urlencoded() 这个中间件,来解析 表单中的 url-encoded 格式的数据
app.use(express.urlencoded({ extended: false }))

app.post('/user', (req, res) => {
  // 在服务器,可以使用 req.body 这个属性,来接收客户端发送过来的请求体数据
  // 默认情况下,如果不配置解析表单数据的中间件,则 req.body 默认等于 undefined
  console.log(req.body)
  res.send('ok')
})

app.post('/book', (req, res) => {
  // 在服务器端,可以通过 req.body 来获取 JSON 格式的表单数据和 url-encoded 格式的数据
  console.log(req.body)
  res.send('ok')
})

// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(80, function () {
  console.log('Express server running at http://127.0.0.1')
})

10. 第三方中间件

body-parser中间件,用来解析表单数据
使用步骤

  1. 安装: npm i body-parser
  2. 导入: const parser = require('body-parser')
  3. 使用: app.use(parser.urlencoded({extend: false}))
// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()

// 1. 导入解析表单数据的中间件 body-parser
const parser = require('body-parser')
// 2. 使用 app.use() 注册中间件
app.use(parser.urlencoded({ extended: false }))
// app.use(express.urlencoded({ extended: false }))

app.post('/user', (req, res) => {
  // 如果没有配置任何解析表单数据的中间件,则 req.body 默认等于 undefined
  console.log(req.body)
  res.send('ok')
})

// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(80, function () {
  console.log('Express server running at http://127.0.0.1')
})

11 自定义解析表单数据中间件


// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()
// 导入 Node.js 内置的 querystring 模块
const qs = require('querystring')

// 这是解析表单数据的中间件
app.use((req, res, next) => {
  // 定义中间件具体的业务逻辑
  // 1. 定义一个 str 字符串,专门用来存储客户端发送过来的请求体数据
  let str = ''
  // 2. 监听 req 的 data 事件
  req.on('data', (chunk) => {
    str += chunk
  })
  // 3. 监听 req 的 end 事件
  req.on('end', () => {
    // 在 str 中存放的是完整的请求体数据
    // console.log(str)
    // TODO: 把字符串格式的请求体数据,解析成对象格式
    const body = qs.parse(str)
    req.body = body
    next()
  })
})

app.post('/user', (req, res) => {
  res.send(req.body)
})

// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(80, function () {
  console.log('Express server running at http://127.0.0.1')
})

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jieyucx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值