Express学习(一)

对于node.js中的其他模块,后面慢慢梳理以下再记录,这两天脑阔都快装不下东西了,今天先记录一下express的学习吧。

1.安装和简单使用

​ 首先新建一个文件夹:

​ 执行npm init进行初始化,方便记录我们安装的包

执行npm iinstall express,稍等片刻安装成功后新建index.js试着搭建服务器,代码如下:

/*
 * @Author:梅子黄时雨
 * @Date: 2023-02-10 10:25:34
 * @LastEditTime: 2023-02-10 11:40:54
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \nodeTest\node\express学习\index.js
 */
//导入,挂载
const express = require('express')
const app = express()

// 第一个参数是路径,支持字符串,字符串模式以及正则模式进行匹配
//第二个参数是个回调函数,具体的放到后续来写~
app.get("/", (req, res) => {
    
    
  //req指的是前端的请求参数,res指的是我们要返回给前端的响应参数
  // send()方法封装了之前的res.write()和res.end(),支持字符串/html模板/json并返回给前端
  // res.send(`
  //   <html>
  //     <h1>Hello world</h1>
  //   </html>
  // `)
  res.send({
    
    
    name: 'libai'
  })
})
//支持的路径模式如下:
//表示匹配/abd或者/abcd的路径
app.get("/ab?cd", (req, res) => {
    
    
  res.send("login")
})
// 表示符合/ab/内容格式的路径
app.get("/ab/:id", (req, res) => {
    
    
  res.send("login")
})
// 表示复合在ab和cd之间添加n个字符串的字符
app.get("/ab*cd", (req, res) => {
    
    
  res.send("login")
})
// 表示当前字符重复n次的路由
app.get("/ab+cd", (req, res) => {
    
    
  res.send("login")
})
// 表示当前字可选的路由 cd可都写也可都不写
app.get("/ab(cd)?ef", (req, res) => {
    
    
  res.send("login")
})
// 正则表达式匹配
app.get("/.*fly$/", (req, res) => {
    
    
  res.send("fly")
})

app.listen(10086, () => {
    
    
  console.log("server start")
})

现在启动服务器,输入以上路径就可以访问对应的页面了(感慨一下:express的路径真的很灵活)

2.中间件

​ 我们将上文提到的回调函数称为中间件。中间件其实指的就是一个函数,可以访问请求对象,响应对象和web应用中处于请求-响应循环流程的中间件,一般被命名为next的变量。如果当前中间件没有终结请求响应循环,则必须调用next方法将控制权交给下一个中间件,否则请求就会挂起。它的功能如下:

  • 执行任何代码

  • 修改请求和相应对象

  • 终结请求-响应循环

  • 调用堆栈中的下一个中间件

    ​ 先写个简单的实例来理解一下中间件: 作为一个后端人员,在前端进行操作并且传递参数给后端时,这个时候的处理一般分为三步:

    1. 拿到前端给的参数先去验证它的token是否过期,
    2. 要去查询数据库
    3. 读取数据做处理返回给前端。

    假设前端需要的数据很多,你需要查好几个表,然后经过一系列复杂的处理才能拼接好,一方面这个时候如果所有的代码都写在一个函数里,那么这个函数体将十分臃肿,另一方面就是这个过程是循序渐进的,先做第一步,再去进行第二步,第三部。这个时候就体现了中间件的作用:先验证token是否通过,如果不通过直接res.send(‘error’),如果通过,那就next()放行去执行下一个中间件,直至有res.send()返回数据和响应给前端。而三个步骤可以封装成三个函数,用法也十分灵活,各位看官请看下图:

/*
 * @Author:梅子黄时雨
 * @Date: 2023-02-10 10:25:34
 * @LastEditTime: 2023-02-10 13:54:28
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \nodeTest\node\express学习\index.js
 */
const express = require('express')
const app = express()

const func1 = (req, res, next) => {
    
    
  // 验证token  
  // 查询数据库
  // 返回内容  
  console.log('验证token')
  // 在函数中要不然用send退出,要不然用next放行
  // 中间件互相通信,在next之前,利用res加属性挂值
  res.name = "李白"
  next()
}
const func2 = (req, res, next) => {
    
    
  res.send({
    
    
    list: [1, 2, 3, 4, 5],
    name: res.name
  })
}
app.get('/home',[func1,func2]) 
app.get("/list", [func1],(req, res) => {
    
    
  res.send({
    
    
    name: "hanxin"
  })
})
app.listen(10086, () => {
    
    
  console.log("server start")
})

中间件的作用就体现出来啦,并且他可以自行配置。这说明个数是我们自定义的,即可以按照需求和降低代码耦合度的原则来配置中间件。

在express中,中间件大概分为如下几种:

  • 应用级中间件

  • 路由级中间件

  • 错误处理中间件

  • 内置中间件

  • 第三方中间件

先写一下应用级中间件和路由中间件吧。

应用级中间件

​ 应用级中间件:类似于vue的导航守卫,用法:app.use(fcuntion),但是要注意使用的位置, 一旦挂在app上,所有的应用都会去使用的,如果说写了一个拦截error的,挂载在了所有的中间件之前,那永远看到的就都是处理错误的页面喽~~话不多说,上代码:

/*
 * @Author:梅子黄时雨
 * @Date: 2023-02-10 10:25:34
 * @LastEditTime: 2023-02-10 13:54:28
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \nodeTest\node\express学习\index.js
 */
const express = require('express')
const app = express()

app.get("/", (req, res) => {
    
    
  res.send({
    
    
    name: 'libai'
  })
})
// 默认路径/放在use方法之前,所以不会去执行以下定义的中间件

// next():执行完当前函数继续执行下一个函数
const func1 = (req, res, next) => {
    
    
  //验证token,cookie是否过期
  // 查询数据库
  // 返回内容
  console.log('验证tooken')
  // 中间件互相通信,在next之前,利用res加属性挂值
  res.name = "李白"
  next()
}
app.use(func1) //挂载func1,以下出现的路径都首先要去执行func1
const func2 = (req, res, next) => {
    
    
  res.send({
    
    
    list: [1, 2, 3, 4, 5],
    name: res.name
  })
}
app.get("/home", [func2])
app.get("/list", (req, res) => {
    
    
  res.send({
    
    
    name: "hanxin"
  })
})
app.listen(10086, () => {
    
    
  console.log("server start")
})

重启服务器,就会发现除了http://localhost:10086这个路径控制台不会出现验证tooken,访问后面的路径都会去执行func1

方便时方便,但是一定要注意挂载的位置啊。

路由级中间件

路由级中间件自然是用来处理路由的啦,比起前文配置一个路由如此麻烦,express提供的路由中间件以及获取参数的方法真的是很简便了。来看下具体用法吧,我们将所有的路由按照目录分好建立相应的文件夹,并设置入口index文件:

/*
 * @Author:梅子黄时雨
 * @Date: 2023-02-10 13:57:07
 * @LastEditTime: 2023-02-10 17:29:13
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \nodeTest\node\express学习\路由中间件.js
 */
//入口文件
const express = require('express')
const app = express()
const HomeRouter = require('./homerouter.js')
const LoginRouter = require('./loginRouter')

function application(req, res, next) {
    
    
  console.log("应用中间件,验证tooken")
  next()
}
app.use(application)
// 应用级别,有顺序的
// 配置post参数的中间件
app.use(express.urlencoded({
    
     extended: false }))//解析前端参数格式
app.use(express.json()) //解析前端参数格式
app.use("/home", HomeRouter)//控制一级匹配 匹配到/home目录下的路由
app.use("/login", LoginRouter)//控制一级匹配 匹配到/login目录下的路由
app.use((req, res) => {
    
    
  res.status(404).send('丢了')//调用send,返回的状态码一定是200,用status可以返回其他的
})//控制一级匹配 匹配到ogin目录下的路由
app.listen(10086, () => {
    
    
  console.log("server start")
})

新建HomeRouter,LoginRouter来存放与各自功能相应的功能,在入口文件引入进行匹配,我们着重看一下如何获取到前端传递的参数,用到一个小工具postaman,我们记录一下利用login来实现传参和获取参数的功能

/*
 * @Author: 梅子黄时雨
 * @Date: 2023-02-10 13:57:07
 * @LastEditTime: 2023-02-10 17:33:45
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \nodeTest\node\express学习\路由中间件.js
 */
const express = require('express')
const router = express.Router()
// 路由级别中间件,响应前端的get请求
 router.get('/', (req, res) => {
    
    
  console.log(req.query) //获取get请求参数
   res.send('login-success')
 })
// 路由级别中间件,响应前端的post请求
router.post('/', (req, res) => {
    
    
  console.log('req>>', req) //获取post请求参数,必须配置中间件  
  res.send({
    
     ok: 4 })
})
module.exports = router

重启服务器,我们测试一下结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44813858/article/details/128978068