express(看完还不会用?来打我!!!)

express基本使用

背景

http模块

  1. 根据不同的请求路径、请求方法,做不同的事情,处理起来比较麻烦
  2. 读取请求体和写入请求体通过流的方式,比较麻烦

基本使用

  1. 安装express

npm i express

以下几个重要的模块可以与 express 框架一起安装:

  • body-parser 用于处理 JSON, Raw, Text 和 URL 编码的数据。
  • cookie-parser 解析Cookie的工具。通过req.cookies可以取到传过来的cookie,并把它们转成对象。
  • multer 用于处理 enctype=“multipart/form-data”(设置表单的MIME编码)的表单数据。
  1. 引入express,创建一个express实例
const express = require('express');
const app = express();
  1. 监听端口
const port = 8080;
// param1 端口号
// param2 成功监听端口的回调
app.listen(port, () => {
    console.log(`server litener on ${port}`);
});
  1. 监听请求
  • 获取请求信息
// app[请求类型](param1: 请求路径, param2处理请求的回调)
app.get('/api/student/:id', (req, res) => {
    console.log('get请求进来了')
    // req 和 res 是express封装之后的对象
    // 获取请求信息
    console.log(req.headers) // 请求头
    console.log("路径", req.path) // 完整请求路径(不包含query)
    console.log("query", req.query) // query
    console.log("params", req.params) // 路径参数
});
// get 请求 localhost:8080/api/student/001?name=qin
// req.path ---> /api/student/001
// req.query ---> { name: 'qin' }
// req.params --->  { id: '001' }
  • 进行响应
app.get('/api/student/:id', (req, res) => {
    console.log('get请求进来了')
    // 设置响应头
    // res.setHeader('a', '123');

    // send会自动进行end()
    // res.send([2, 3, 4]);

    // 设置状态码 + 重定向 (可链式调用,每次执行方法返回的都是一个response对象)
    // res.status(302).header("location", "https://ent.curtao.com").end();

    // 重定向简写(状态码,重定向的地址)
    res.redirect(302, "https://ent.curtao.com");
})
  • 监听所有的get请求(建议放到最下方,所有get请求的路径找不到时,才执行)
app.get("*", (req, res) => {
    console.log('任意get请求', req.path)
})

express中间件

一个express处理函数就是一个中间件

中间件处理细节

  • 如果后续已经没有了中间件
  • 当匹配到了请求后,交给第一个处理函数处理
  • 函数中需要手动的交给后续中间件处理
// 两个参数req, res
// 三个参数req, res, next
// 四个参数err, req, res, next
// 此时路径是精确匹配
app.get('/api/student', (req, res, next) => {
    console.log('中间件1');
    next(); // 执行下一个中间件
}, (res, req) => {
    console.log('中间件2');
});

错误处理中间件

- 如果在某一个中间件发生了错误(此处可手动抛出错误进行测试throw new Error('XXX'))
- 相当于调用了next(错误对象)
- 寻找后续的错误处理中间件,如果没有后续的错误处理中间件,则响应500。(express认为具有四个参数(err, req, res, next) => {}的中间为错误处理中间件)
// throw new Error('XXX') ---> next(new Error('XXX'))
// 四个参数
(err, req, res, next) => {} // --->错误处理中间件    
// 此种方法使用中间件,只能匹配指定路径(/student)get请求发生的错误
app.get('/student', errorMiddleWare);
// 此种方法使用中间件,可以匹配所有路径get请求发生的错误
app.get('*', errorMiddleWare);

错误处理中间件一般放到最后,对所有请求的错误进行统一处理
app.use(’*’, errorMiddleWare); // 可匹配所有请求

// 这样使用中间件:可匹配/student, /student/XXX......路径下的所有请求
app.use('/student', errorMiddleWare);

响应静态页面的中间件express.static())

/*
 * 下面这段代码的作用:
 * 当请求时,会根据请求路径(req.path),从指定的目录中寻找是否存在该文件,
 * 如果存在,直接响应文件内容,而不再移交给后续的中间件
 * 如果不存在文件,则直接移交给后续的中间件处理
 * 默认情况下,如果映射的结果是一个目录,则会自动使用index.html文件
 */
const staticRoot = path.resolve(__dirname, "../dist");
app.use(express.static(staticRoot));

express解析body请求体

body在node中需要用流的方式读取,express提供了解析消息体的中间件
1. express.urlencoded({extended: true, …}) // 使用qs库进行解析
- 解析请求头的Content-Type为application/x-www-form-urlencoded的请求体
2. express.json([options])
- 解析请求头的Content-Type为application/json的请求体

express路由

// student.js
const express = require("express");
const router = express.Router();

router.get('/', (req, res) => {
    res.send('获取所有学生');
}); 

router.get('/:id', (req, res) => {
    res.send('获取单个学生');
}); 

router.post('/', (req, res) => {
    res.send('添加一个学生');
});

router.delete('/:id', (req, res) => {
    res.send('删除一个学生');
}); 

router.put('/:id', (req, res) => {
    res.send('修改一个学生');
});

module.exports = router;

// index.js
// 处理 api 的请求, 所有基地址为/api/student的请求, 都会通过此路由进行处理
app.use('/api/student', require("./api/student"));

服务端发送http请求报错的统一处理函数

// 获取单个学生
router.get('/:id', async (req, res) => {
    // 此处使用Promise模拟http请求中的报错
    const result = await new Promise((resolve, reject) => {
        throw new Error('http请求发生错误');
    });
    res.send(result);
});  
// 常规解决方法
router.get('/:id', async (req, res) => {
    try {
        const result = await new Promise((resolve, reject) => {
            throw new Error('http请求发生错误');
        });
        res.send(result);
    } catch (error) {
        next(error);
    }
}); 
// 可抽取公共方法来统一处理异步错误
// 统一处理异步错误的方法
const asyncHandler = (handler) => {
    return async (req, res, next) => {
        try {
            const result = await handler(req, res, next);
            res.send(result);
        } catch (error) {
            next(error);
        }
    };
}
router.get('/:id', asyncHandler(async (req, res, next) => {
    // 获取单个学生的http请求
    return await new Promise((resolve, reject) => {
        throw new Error('http请求发生错误');
    });
})); 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值