1,209

express实际上是对nodejs内置http进行封装后的第三方包,其中提供了快捷创建web服务器以及处理请求路由的方法,使我们可以更加方便快捷的实现一个web服务器项目。

基于nodejs的web服务器,连接使用数据库
基于nodejs的web服务器,连接使用redis
基于nodejs的web服务器,实现用户登陆注册等接口功能

Github代码仓库地址

一、创建web服务器

1、初始化项目并安装express包

初始化项目

npm init -y

安装express

npm i express

2、创建服务器

1、创建一个index.js文件 2、导入express 3、创建服务器 4、调用listen启动服务器(listen传入两个参数:端口号,回调函数) 5、在当前目录下使用node index.js启动该程序,控制台打印出:Server is running on port 3000,则表示服务器在3000端口启动成功

// 导入express
const express = require('express')
// 创建服务器
const app = express()
// 调用listen启动服务器
app.listen(3000, () => {
    console.log('Server is running on port 3000')
node index.js

3、监听get,post请求

监听get,post请求(req:请求参数,res:响应参数),使用res.send(data)向web段响应数据

// 监听GET请求
app.get('/', (req, res) => {
    res.send('Hello, GET request received!')
// 监听POST请求
app.post('/', (req, res) => {
    res.send('Hello, POST request received!')

4、获取请求参数

web端向服务器传递参数,可以通过params,query,body传递参数,其中一般get请求使用params,query传递参数,post请求使用body传递参数
1、get请求使用params获取参数,请求url:http://127.0.0.1:3000/test/123,此时web获取响应id:123

// 获取params参数
app.get('/test/:id', (req, res) => {
    const id = req.params.id
    res.send(`id: ${id}`)

2、get请求使用query获取参数,请求url:http://127.0.0.1:3000/test?id=123&name=whg,此时web获取响应id: 123,name: whg

// 获取query参数
app.get('/test', (req, res) => {
    const id = req.query.id
    const name = req.query.name
    res.send(`id: ${id},name: ${name}`)

3、post请求使用body获取参数,请求url:http://127.0.0.1:3000/test。对于post请求,我们首先使用app.use中间件来解析请求的表单数据。通过express.urlencoded中间件来解析x-www-form-urlencoded格式的表单数据,其中extended: false表示不使用第三方库来处理嵌套的对象。如果你需要处理其他类型的数据(例如JSON数据),你可以使用express.json中间件。(中间件概念后续会有详细介绍) 请求数据:{id: 123, name: whg},响应数据:testData: {id: 123, name: whg}

app.use(express.urlencoded({ extended: false }))
app.use(express.json())
// 获取body参数
app.post('/test', (req, res) => {
    const testData = req.body
    res.send(`testData: ${testData}`)

二、express路由

在Express中,路由(Routing)是指将不同的HTTP请求映射到相应的处理程序或控制器的过程。Express提供了一种简单而灵活的方式来定义和管理路由,使开发人员能够处理不同的URL路径和HTTP方法。

1、直接使用路由

监听get,post请求中的/test路由,当请求url为http://127.0.0.1:3000/test时,进入对应的请求处理函数中

// 监听GET请求/test路由
app.get('/test', (req, res) => {
    res.send('Hello, GET request received!')
// 监听POST请求/test路由
app.post('/test', (req, res) => {
    res.send('Hello, POST request received!')

2、使用路由器

路由器是一个中间件,用于将具有共同路径前缀的相关路由组合在一起。它可以看作是一个独立的模块,负责处理特定的URL路径。使用路由器可以将应用程序的路由逻辑组织成模块化的方式,提高代码的可维护性和可读性
创建用户登陆注册路由器模块:users.js

// 导入express
const express = require('express')
// 创建路由器
const router = express.Router()
// 使用路由器监听路由
router.post('/login', (req, res) => {
    res.send('login success')
router.post('/register', (req, res) => {
    res.send('register success')
// 导出路由器
modules.exports = router

创建用户信息相关路由器模块:userInfo.js

// 导入express
const express = require('express')
// 创建路由器
const router = express.Router()
// 使用路由器监听路由
router.post('/setUserInfo', (req, res) => {
    res.send('setUserInfo success')
router.post('/getUserInfo', (req, res) => {
    res.send('getUserInfo success')
// 导出路由器
modules.exports = router

在index.js中导入并注册该路由器 app.use注册路由时可传入两个参数,第一个参数为统一前缀(可选,不传则默认没有前缀),第二个参数为路由器。当url为http://127.0.0.1:3000/login时进入登录路由处理函数中,当url为http://127.0.0.1:3000/api/setUserInfo时,进入设置用户信息路由处理函数中

// 导入路由器
const userRouter = require('./users')
const userInfoRouter = require('./userInfo')
// 注册路由
app.use(userRouter)
app.use('/api', userInfoRouter)

3、封装路由处理函数

将路由相关逻辑进一步模块化(以user.js为例) 创建routerHandler文件夹,存放users.js文件(注意,和router文件夹下的文件名相同,可清晰看出路由器文件和处理函数文件的一一对应关系)

// 登录路由处理函数
exports.login = (req, res) => {
    res.send('login success')
// 注册路由处理函数
exports.register = (req, res) => {
    res.send('register success')

创建router文件夹,存放users.js文件

// 导入express
const express = require('express')
// 创建路由器
const router = express.Router()
// 导入路由处理函数
const { login, register } = require('../routerHandler/user.js')
// 使用路由器监听路由
router.post('/login', login)
router.post('/register', register)
// 导出路由器
modules.exports = router

三、express中间件

Express中间件(Middleware)是在请求和响应之间处理HTTP请求的功能组件。中间件函数可以访问请求对象(req)、响应对象(res)和应用程序的下一个中间件函数(next)。中间件函数可以用于执行各种任务,例如身份验证、日志记录、错误处理等。使用中间件可以将应用程序的处理逻辑分解为可重用和可组合的部分,提高代码的可维护性和可扩展性。中间件大致分为以下5种,下面我们使用模块化的思想将所有自定义的中间件放在common文件夹的middleware.js文件中

1、应用级中间件(Application-level Middleware)

应用级中间件又称为全局中间件,这些中间件绑定到应用程序对象(app)上,并在所有路由之前执行。它们可以用于处理应用程序级别的任务,如日志记录、身份验证、错误处理等。使用app.use()方法将应用级中间件添加到应用程序中。 中间件函数中一定要调用next()方法,否则会报错

// 定义一个应用级中间件,该中间件封装了res.send()方法
exports.resSendMiddleware = (req, res, next) => {
    res.commonResSend = (status, message, data) => {
        res.send({
            status,
            message,
            data: data ? data : null
    next()

注意:全局中间件一般要放在路由中间件之前

// 导入中间件
const { resSendMiddleware } = require('../common/middleware.js')
// 注册全局中间件
app.use(resSendMiddleware)
// 注册路由中间件
// TODO

2、路由级中间件(Router-level Middleware)

路由级中间件又称为局部中间件这些中间件与特定的路由绑定,并在特定路由处理程序之前执行。它们用于在特定路由上执行一些操作,如身份验证、请求处理等。使用express.Router()创建路由对象,然后使用router.use()将路由级中间件添加到路由对象中。

// 定义一个路由级中间件,该中间件封装了校验登录数据合法性
exports.verifyLogin = (req, res, next) => {
    const userInfo = req.body
    // 校验逻辑
    // TODO
    next()
// 导入路由处理函数
const { login, register } = require('../routerHandler/user.js')
// 导入中间件
const { verifyLogin } = require('../common/middleware.js')
// 使用路由器监听路由
router.post('/login', verifyLogin, login)
router.post('/register', register)
// 导出路由器
modules.exports = router

3、错误处理中间件(Error Handling Middleware)

这些中间件用于处理发生在路由处理程序中的错误。它们在其他中间件和路由处理程序之后定义,并使用四个参数(err, req, res, next)来捕获错误并处理它们。使用app.use()将错误处理中间件添加到应用程序中。

// 定义一个错误中间件,捕捉错误
exports.handleError = (err, req, res, next) => {
    if (err.name === 'UnauthorizedError') {
        // JWT 认证失败
        res.commonResSend(401, '身份认证失败')
// 导入中间件
const { resSendMiddleware, handleError } = require('../common/middleware.js')
// 注册全局中间件
app.use(resSendMiddleware)
// 注册路由
// TODO
// 注册错误中间件
app.use(handleError)

4、第三方中间件(Third-party Middleware)

这些中间件是由第三方开发人员创建的,可以通过NPM安装并在Express应用程序中使用。第三方中间件可以提供各种功能,如身份验证、日志记录、压缩等。使用app.use()将第三方中间件添加到应用程序中。 例如处理跨域中间件cors,使用npm i cors安装之后,可直接引用并注册

// 导入cors
const cors = require('cors')
// 导入中间件
const { resSendMiddleware, handleError } = require('../common/middleware.js')
// 注册解决跨域问题中间件
app.use(cors)
// 注册全局中间件
app.use(resSendMiddleware)
// 注册路由中间件
// TODO
// 注册错误中间件
app.use(handleError)

5、内置中间件(Built-in Middleware)

Express提供了一些内置的中间件,可直接在应用程序中使用,而无需安装额外的包。例如,express.urlencoded(),express.json()用于解析请求的JSON数据,express.static()用于提供静态文件等。

// 导入cors
const cors = require('cors')
// 导入中间件
const { resSendMiddleware, handleError } = require('../common/middleware.js')
// 注册解决跨域问题中间件
app.use(cors)
// 注册内置中间件
app.use(express.urlencoded({ extended: false }))
app.use(express.json())
app.use(express.static('public'))
// 注册全局中间件
app.use(resSendMiddleware)
// 注册路由中间件
// TODO
// 注册错误中间件
app.use(handleError)

四、代码热更新

为了避免我们每次修改代码后都需要执行一次node index.js来重新运行代码,我们可以全局安装nodemon来监视代码修改并自动重新启动应用程序

npm install -g nodemon
nodemon index.js
    Harbour
        高级前端工程师
       
粉丝