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应用程序打下坚实基础。
相关推荐
凤山老林3 分钟前
Spring Boot 集成 ShardingSphere-Encrypt 实现字段级实时脱敏
java·spring boot·后端·数据脱敏
vipxieliang3 分钟前
ValidX v1.2.0 更新日志
java·后端
Zane199411 分钟前
只改一个方向的引用,循环引用就能立刻被回收?一文讲透 weakref 弱引用
后端·python
长大198811 分钟前
窗口函数用不好反而更慢?SQL Server中OVER子句的4个性能陷阱
后端
大黄评测11 分钟前
MERGE语句有Bug?SQL Server官方不推荐的背后真相与替代方案
后端
长大198813 分钟前
TempDB 爆满导致系统卡死?SQL Server TempDB 瓶颈诊断与根治方案
后端
PedroQue9913 分钟前
v2.6.0 新增全局返回守卫与 iOS 侧滑拦截,补齐跨端路由拦截能力
前端·uni-app
lichenyang45316 分钟前
从「房间」到「实时通知」:用 NestJS + Socket.IO 实现团队邀请的完整工程实践
前端·后端
大黄评测16 分钟前
为什么你的SQL查询慢?这7个执行计划陷阱90%的人都踩过
后端
沙盘客25 分钟前
AFSIM 示例解读(09)· 传感器全家桶 sensor_demos(下):ESM / SAR / 被动测向
c++·经验分享·后端