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应用程序打下坚实基础。
相关推荐
Fan_web1 分钟前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
安冬的码畜日常3 分钟前
【CSS in Depth 2 精译_044】第七章 响应式设计概述
前端·css·css3·html5·响应式设计·响应式
莹雨潇潇1 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
Jiaberrr1 小时前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui
杨哥带你写代码1 小时前
足球青训俱乐部管理:Spring Boot技术驱动
java·spring boot·后端
AskHarries2 小时前
读《show your work》的一点感悟
后端
Tiffany_Ho2 小时前
【TypeScript】知识点梳理(三)
前端·typescript
A尘埃2 小时前
SpringBoot的数据访问
java·spring boot·后端
yang-23072 小时前
端口冲突的解决方案以及SpringBoot自动检测可用端口demo
java·spring boot·后端
Marst Code2 小时前
(Django)初步使用
后端·python·django