Node.js Web框架入门:使用Express搭建简单应用并深入了解中间件与错误处理(下)

上节课我们讲到使用express脚手架快速搭建express应用,本次课程我们继续聊聊express。

  1. 开始将app.js中的内容改成ts
  • 改写
    • 先直接将内容复制到app2.ts
    • yarn add @types/node@16.15.0 --dev,这样才能使用require
    • yarn add @types/express@4.16.1 --dev,这样才能使用require
    • 可以用import代替require
    • 可以用const代替var
    • 需RequestHandler和ErrorRequestHandler断言
js 复制代码
import { ErrorRequestHandler, RequestHandler } from 'express-serve-static-core';
...
app.use(function (req, res, next) {
  next(createError(404));
} as RequestHandler);
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};
  res.status(err.status || 500);
  res.render('error');
  next()
} as ErrorRequestHandler);

module.exports = app;
  • 将bin/www中的入口改为app2.ts
  • 添加yarn start ts脚本,将node改为ts-node
  • 其它地方想要用ts的也需要这样改
  1. 深入了解express编程模型
  • app.use()的作用
  • 创建express-demo2,使用刚才创建的starter
bash 复制代码
clone git@github.com:codingories/express-starter-1.git .
yarn install
  • 删除app.js自己重新写一下,运行node-dev app.js
js 复制代码
const express = require('express')

const app = express()

app.use((request, response, next)=> {
  console.log(request.url)
  response.write('hi')
  next()
})

app.use((request, response, next)=> {
  console.log(2)
  response.write('hi')
  next()
})

app.use((request, response, next)=> {
  response.end()
  next()
})


app.listen(3000, () => {
  console.log('正在 listen 3000')
})
  • 访问localhost:3000,得到hihi,通过这个例子我们可以简单的体会一下app.use使用中间件
  1. 什么是中间件
  • express的编程模型
  • 中间件的概念:通过app.use注册了一系列中间件。允许你在请求到达路由处理之前或之后执行一些操作
  • 例子
js 复制代码
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
  • 中间件的优点
    • 这种模型使得每个功能都能通过一个函数实现
    • 然后通过app.use将这个函数整合起来
    • 如果把函数放到文件或npm里,就实现了模块化
  • 自己写一个中间件,新建logger.js
js 复制代码
const logger = (prefix) => {
  return (request, response, next) => {
    console.log(`${prefix} ${request.url}`)
    next()
  }
}

module.exports = logger
  • 然后在app.js中使用,这样就独立完成了一个logger的中间件
js 复制代码
const fn = logger('dev')

app.use(fn)

app.use((request, response, next)=> {
  response.end()
  next()
})
  • 题外话,我们可以将以下代码设置成live template来快速生成,之后直接输入app.use加tab就可以生成,$end表示停的位置
js 复制代码
app.use((request, response, next)=> {

})
  • app.use如何实现路由
js 复制代码
app.use((request, response, next)=>{
  if(request.path==='/xxx' && request.method === 'get') {
    request.write('home')
  }
  next()
})
  • 路由更简单的实现方式
js 复制代码
const fn = () => {}
app.use('/aaa', fn)
app.get('/yyy', fn)
app.post('/zzz', fn) 
app.route('/xxx').all(f1).get(f2).post(f3)
  • 处理路由我们更推荐用express.Router()
    • 通过express.Router(),可以将每个路由的处理逻辑独立分离,使代码更易于维护。
    • 具体代码
js 复制代码
// 创建一个路由器
const router = express.Router();

// 定义路由处理程序
router.get('/', (req, res) => {
  res.send('首页');
});

router.get('/about', (req, res) => {
  res.send('关于我们');
});

router.get('/contact', (req, res) => {
  res.send('联系我们');
});

// 将路由器挂载到'/app'路径上
app.use('/', router);

app.listen(3000, () => {
  console.log('正在 listen 3000')
})
  1. 错误处理
  • 例子
js 复制代码
// 模拟一个可能出错的路由处理
app.get('/error', (req, res, next) => {
  // 在这个例子中,模拟一个异步操作,比如查询数据库时发生了错误
  setTimeout(() => {
    // 模拟错误
    next(new Error('这是一个模拟的错误'));
  }, 1000);
});

// 错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.stack);

  // 判断错误类型并发送相应的响应
  if (err instanceof SyntaxError) {
    res.status(400).send('Bad Request');
  } else {
    res.status(500).send('Something went wrong!');
  }
});

// 启动服务器
app.listen(3000, () => {
  console.log('服务器正在监听端口 3000');
});
  • next(error),会直接进入errorHandler,不执行后面的中间件
  • 如何自定义errorHandler
js 复制代码
app.use((err, req, res, next) => {
  ...
});
  1. 总结
  • 本次课程我们深入了解Express的编程模型与中间件。
  • 首先,通过Curl命令、HTTP请求与响应的处理,我们夯实了对Web框架的基础认识。
  • 接着,我们将探讨Express的编程模型,了解中间件的概念与优势,并通过自定义中间件和路由进行实践。
  • 进一步地,我们将学习错误处理的重要性,通过示例了解如何处理可能出错的路由,以及如何自定义错误处理中间件。
    • 通过这些实例,我们将更深入地了解Express的强大功能。
  • 最后,让我们继续深入学习Express,为构建强大的Node.js应用程序打下坚实基础。
相关推荐
狗头大军之江苏分军1 小时前
《潮水漫过十七岁》开学了
后端
苏三说技术1 小时前
如何看待GPT-6在UP主众测中碾压夺冠?它是现在最强大模型吗?
后端
mldong2 小时前
一份 JSON,一条能跑的审批流:把报销流程送上工作流引擎
后端·架构
wno7042 小时前
Spring Boot WebFlux增删改查
java·spring boot·后端
Captaincc2 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
aramae3 小时前
模拟实现strlen()函数 (C语言)
c语言·开发语言·后端
计算机魔术师3 小时前
德国Wiki被黑后两周,OpenAI终于把模型失控的账本摊开了
前端
kyriewen4 小时前
我让 AI 当面试官面了我一轮:第 3 个追问我就卡住了(附 10 道追问清单)
前端·面试·ai编程
IT_陈寒4 小时前
Python的GIL把我坑惨了,多线程跑得比单线程还慢
前端·人工智能·后端
分支预测失败4 小时前
RISC-V 时间子系统深度专题:mtime 访问路径、SBI 定时器与 Linux tickless 协同
后端