【Express】Express入门使用

贺靖
2023-12-01

express

一、简介

官网:http://expressjs.com/

Express 是一个快速,简单,极简的 Node.js web 应用开发框架。通过它,可以轻松的构建各种 web 应用,通过中间件的方式集成了许许多多的外部插件来处理 HTTP 请求。

Wxpress可用于

二、入门Hello World

准备一个空文件夹。

1、安装Express:cnpm install express

2、创建app.js

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

// req 和 res 对象来处理请求和响应的数据。
app.get('/', (req, res) => {
  res.send('Hello World!')
  res.end()
})

app.listen(3000, () => {
  console.log(`Example app listening at http://localhost:3000`)
})

三、路由

路由是指确定应用程序如何响应客户端对特定端点的请求,该特定端点是URI(或路径)和特定的HTTP请求方法(GET,POST等)。每个路由可以具有一个或多个处理程序函数,这些函数在匹配该路由时执行。

格式:app.METHOD(PATH, HANDLER)

  • app 是 Express 实例
  • METHOD 是小写的 HTTP 请求方法
  • PATH 是服务器上的路径
  • HANDLER 是当路由匹配时执行的功能
// get请求
app.get('/user', (req, res) => {
  res.send('get')
  res.end()
})

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

// put请求
app.put('/user', (req, res) => {
  res.send('put')
  res.end()
})

// delete请求
app.delete('/user', (req, res) => {
  res.send('delete')
  res.end()
})

案例

通过案例进行了解。对JSON数据进行CRUD操作

1、app.json

{
  "todos": [
    {
      "id": 1,
      "todo": "写作业"
    },
    {
      "todo": "吃饭",
      "id": 2
    }
  ]
}

2、封裝数据库操作 db.js

const { promisify } = require('util')
const fs = require('fs')
const path = require('path')
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)

const dbPath = path.join(__dirname, './app.json')

exports.getDb = async () => {
  const data = await readFile(dbPath, 'utf8')
  return JSON.parse(data)
}

exports.setDB = async (body) => {
  const currentData = await readFile(dbPath, 'utf8')
  let cd = JSON.parse(currentData)
  console.log(cd)
  cd.todos.push({
    todo: body.todo,
    id: cd.todos.length
  })
  await writeFile(dbPath, JSON.stringify(cd, null, '  '), 'utf8')
}

3、app.js

const express = require('express')
// const fs = require('fs')
const {getDb, setDB} = require('./db')

const app = express()

// ---不配置则req.body获取不到值
// 配置解析表单JSON请求体
app.use(express.json())
// app.use(express.urlencoded()) // 来解析表单中的 url-encoded 格式的数据

//获取todo列表
app.get('/todo/list', async (req, res) => {
  // console.log(req.url) // 请求链接
  // console.log(req.method) // 请求方法
  // console.log(req.headers) //请求头
  // console.log(req.search) //请求头
  const data = await getDb()
  res.send(data)
  res.end()
})

// 获取某一个todo
app.get('/todo/:id', async (req, res) => {
  console.log(`${req.params.id}`)
  const data = await getDb()
  res.send(data.todos.filter(item => item.id == req.params.id)[0] || '暂无数据')
  res.end()
})

// 添加todo
app.post('/todo/add', async (req, res) => {
  console.log(req.body, '===========')
  await setDB(req.body)
  res.status(200).json({"status": 200})
  res.end()
})

app.listen('3000', () => {
  console.log('项目启动,端口3000')
})

四、中间件

在 Express 中,中间件就是一个可以访问请求对象、响应对象和调用 next 方法的一个函数。

Express 中间件和 AOP 面向切面编程就是一个意思,就是都需要经过经过的一些步骤,不去修改自己的代码,以此来扩展或者处理一些功能

在中间件函数中可以执行以下任何任务:

  • 执行任何代码
  • 修改 request 或者 response 响应对象
  • 结束请求响应周期
  • 调用下一个中间件

分类

  • 应用程序级别中间件
  • 路由级别中间件
  • 错误处理中间件
  • 内置中间件
  • 第三方中间件

1、应用程序级别中间件

例如我们想输出请求日志,请求方法、请求路径、请求时间,我们可以这样做:

app.use(function (req, res, next) {
  console.log('Time:', Date.now())
  next()
})

限定请求路径:

app.use('/todo/:id', function (req, res, next) {
  console.log('Request Type:', req.method)
  next()
})

限定请求方法 + 请求路径:

app.get('/user/:id', function (req, res, next) {
  res.send('USER')
})

多个请求函数:

app.use('/todo/:id', function (req, res, next) {
  console.log(123)
  next()
}, async function (req, res) {
  console.log(`${req.params.id}`)
  const data = await getDb()
  res.send(data.todos.filter(item => item.id == req.params.id)[0] || '暂无数据')
})

要从路由器中间件堆栈中跳过其余中间件功能,可以调用 next('route') 将控制权传递给下一条路由。

中间件也可以在数组中声明为可重用。

function time (req, res, next) {
  console.log('Request time:', Date.now())
  next()
}

function logMethod (req, res, next) {
  console.log('Request Type:', req.method)
  next()
}

var logStuff = [time, logMethod]
app.get('/todo/:id', logStuff, function (req, res, next) {
  res.send('todo Info')
})

2、路由器级中间件

使用 router.use()router.METHOD() 函数加载路由器级中间件。

按照之前的代码进行修改,创建router.js

const express = require('express')
const {getDb, setDB} = require('./db')
const router = express.Router()

router.get('/', (res, req) => {
  req.send("路由级别")
})

router.get('/list', async (req, res) => {
  const data = await getDb()
  res.send(data)
  res.end()
})

router.use('/:id', function (req, res, next) {
  console.log(123)
  next()
}, async function (req, res) {
  console.log(`${req.params.id}`)
  const data = await getDb()
  res.send(data.todos.filter(item => item.id == req.params.id)[0] || '暂无数据')
})

router.post('/add', async (req, res) => {
  await setDB(req.body)
  res.status(200).json({"status": 200})
  res.end()
})

module.exports = router

app.js简化

const router = require('./router')

const app = express()
//使用,注意:第一个参数如果存在,则证明访问route中的路由访问时需要添加第一个参数,/todo/
app.use('/todo', router)

3、错误处理中间件

如果将任何内容传递给该next()函数(字符串除外’route’),Express都会将当前请求视为错误,并且将跳过所有剩余的非错误处理路由和中间件函数。

app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})

4、404处理

在所有路由中间件最后添加下面中间件,没有被路由匹配到的请求都将进入这里。

app.use((req, res, next) => {
	res.status(404).send('404 Not Found.')
})

5、第三方中间件

例如:日志输出中间件morgan
安装方法:cnpm install morgan --save
使用:

const morgan = require('morgan')
const app = express()
app.use(morgan('dev'))
 类似资料: