Express框架路由处理函数和中间件函数使用注意事项梳理

假设Express生成的应用实例名称为 app。我使用的是 TypeScript,关于如何搭建 TypeScript语言的 Node.js 开发环境,请参考这个链接:搭建Node.js+TypeScript开发环境要点及注意事项
也可以执行以下命令直接拉取仓库,将会得到一个框架。

git clone git@gitee.com:war_horse/framework_for_node.js_using_ts.git

实质意义

  • 他们本质都是处理各种路由和请求方式的函数,两者的界限并不是很清晰,添加方式和运行机制大致相同;
  • 他们都有 req、res 和 next 参数;
  • 他们都能按指定条件匹配不同的路由和请求方式。

添加方式

他们都可以使用app.use 、 app.METHOD(METHOD代表 post、get、patch、put、delete 等请求方法中的一种,下同)和 app.all(all 代表所有请求方法,下同) 的方式添加到应用实例;一般情况下,用 app.use 方式添加的函数称为“中间件处理函数”,而用其他方式添加的函数称为“路由处理函数”。

  • 示例 1:中间件函数的各种添加方式

    import express from 'express';
    const app = express();
    
    /**
     * 尝试用各种方式添加中间件处理函数
     */
    app.use((req, res, next) => {
        console.log('我是采用 app.use 方法添加的中间件');
        next();
    })
    app.get('/',(req,res,next) => {
        console.log('我是采用 app.get 方法添加的中间件')
        next()
    })
    app.all('/',(req,res,next) => {
        console.log('我是采用 app.all 方法添加的中间件')
        res.end()
    })
    
    app.listen(3000, () => {
        console.log('服务已成功启动,监听端口:3000')
    })
    

    当用浏览器打开 http://localhost:3000 的时候,在服务器端将输出以下结果:
    在这里插入图片描述

  • 实例 2:路由处理函数各种添加方式

    import express from 'express';
    const app = express();
    
    /**
     * 用各种方式添加路由处理函数
     */
    app.use('/items',(req, res, next) => {
        console.log(`我是采用 app.use 方法添加的路由处理函数。当前请求方式:${req.method}`);
        next();
    })
    app.get('/items',(req,res,next) => {
        console.log('我是采用 app.get 方法添加的路由处理函数')
        next()
    })
    app.post('/items',(req,res,next) => {
        console.log('我是采用 app.post 方法添加的路由处理函数')
        next()
    })
    app.all('/items',(req,res,next) => {
        console.log(`我是采用 app.all 方法添加的路由处理函数。当前请求方式:${req.method}`)
        res.end()
    })
    
    app.listen(3000, () => {
        console.log('服务已成功启动,监听端口:3000')
    })
    

    当用 get 方式 向 http://localhost:3000/items发送请求的时候,服务器端输出以下结果,可以看到,除了 app.get 方式以外, app.use 和 app.all 方式添加的路由处理函数都匹配到了:
    在这里插入图片描述
    我们再次用 post 方式向http://localhost:3000/items 发送请求,输出以下结果:
    在这里插入图片描述

存储和调用方式

通过观察以上的示例可以得出结论:他们在应用实例内部数组的形式存储,按添加和匹配的顺序被调用;前序匹配的函数调用了 next 方法,后一个匹配的函数才会被调用。

各种添加方式的注意事项

app.use方法

app.use 方法表示匹配所有的请求方式,他有两种参数形式,既可以指定路由,也可以不指定路由,但处理函数不能省略 :

  • 如果只传递了一个参数,那么这个参数必须是一个函数,这个函数匹配所有请求方式和路径:

    import express from 'express';
    const app = express();
    
    /**
     * app.use 方法研究
     */
    app.use((req, res) => {
        console.log(`采用 app.use 直接添加一个处理函数的方式,能匹配所有路径和请求方式,当前请求方式:${req.method},当前请求路径:${req.path}`)
        res.end()
    })
    app.listen(3000, () => {
        console.log('服务已成功启动,监听端口:3000')
    })
    

    以 post 方式向 http://localhost:3000/abded 发送请求,结果如下:
    在这里插入图片描述
    以 delete 方式向http://localhost:3000/123456发送请求,结果如下:
    在这里插入图片描述
    以上示例能证明,app.use 直接添加处理函数(但不指定路径)的方式能匹配所有路径和请求方式。

  • 如果传递了两个参数,则第一个参数必须是一个路径字符串,第二个参数是一个函数,这个函数匹配这个路径下的所有请求方式,以 get 请求为例:

    import express from 'express';
    const app = express();
    
    /**
     * app.use 方法研究
     */
    app.use('/test',(req, res) => {
        console.log(`采用 app.use 向一个路由添加处理函数,能匹配所有请求方式,当前请求方式:${req.method}`)
        res.end()
    })
    app.listen(3000, () => {
        console.log('服务已成功启动,监听端口:3000')
    })
    

    当向 http://localhost:3000/test 发送各种类型请求之后,输出以下结果:
    在这里插入图片描述

app.METHOD 和 app.all方法

方式添加的路由处理函数或者中间件函数,至少接受两个参数,第一个参数必须是路径字符串,其他特性与 app.use 方法一样。

确保他们正常运行的注意事项

  • 中间件处理函数和路由处理函数是按照匹配规则和添加的顺序先后调用的;可以这样理解,一次请求过程中,首先找出能匹配这个请求方式和路由的中间件处理函数和路由处理函数,然后按照他们添加的顺序依次执行;
  • 匹配成功的函数必须内部调用 next 方法,才能确保后续匹配成功的函数能被调用;
  • 调用res.download、res.send、res.end、res.json、res.jsonp、res.redirectr、res.render、res.sendFile、res.sendStatus 方法中的一种能完成一次请求处理;
  • 一次响应的处理过程中,以上方法的调用有且仅有一次,否则会出错。不调用的话,程序将会处于挂起状态,调用1 次以上服务端会报错。
  • 如果在一个匹配成功的函数内调用了以上完成请求处理方法中的任意一个,后续匹配成功的函数将不能被调用;
  • 如果一个匹配成功的函数内部既没有调用 next,也没有调用完成请求处理的方法,那么应用实例会被挂起,在浏览器端也会一直等待响应。
<think>好的,用户想了解Express框架中请求与路由处理函数的对应关系。我需要根据提供的引用内容来组织回答。首先,引用[1][2]详细说明了路由的定义结构,应该从这里入手。路由由请求类型、URL地址处理函数组成,结构是app.METHOD(PATH, HANDLER)。需要解释每个部分的作用,比如METHOD对应HTTP方法,PATH是URL路径,HANDLER是处理函数。然后提到匹配过程,当请求的方法路径都匹配时,才会执行对应的处理函数。引用[3]可能涉及处理函数中的异步操作,但用户的问题主要关注对应关系,所以可能不需要深入讨论回调地狱的解决方法。接下来,需要举例说明,比如GETPOST请求的处理,如app.get('/', ...)app.post('/login', ...),这能帮助用户更直观地理解。另外,要确保使用中文,并且数学公式如果有的话要正确格式,但这个问题可能不需要数学公式。最后生成相关问题,可能涉及路由匹配顺序、参数处理、中间件影响等。需要检查是否遗漏了关键点,比如路由参数的传递或者中间件的作用,但根据引用内容,用户主要问的是对应关系,所以保持重点在结构上。确保回答结构清晰,分点说明,并正确引用来源。</think>在 Express 框架中,请求与路由处理函数的对应关系通过以下三要素建立: ### 1. 路由三要素 路由由**请求类型**、**URL 路径****处理函数**组成,语法格式为: $$app.METHOD(PATH, HANDLER)$$ - **METHOD**:HTTP 请求方法(如 GET、POST、PUT、DELETE) - **PATH**:客户端请求的 URL 地址(如 `/login`、`/api/data`) - **HANDLER**:匹配成功后执行的处理函数,接收 `(req,res)` 参数[^1][^2] ### 2. 路由匹配过程 ```javascript // 匹配 GET 请求且路径为 '/' app.get('/', (req, res) => { res.send('首页内容') }) // 匹配 POST 请求且路径为 '/submit' app.post('/submit', (req, res) => { res.status(201).send('数据提交成功') }) ``` 当收到请求时,Express 会按照**声明顺序**依次检查: 1. 请求方法是否匹配 2. URL 路径是否匹配 3. 执行首个完全匹配的处理函数[^1] ### 3. 特性说明 - **精确匹配**:路径 `/user` 不会匹配 `/user/profile` - **路由参数**:可通过 `:id` 形式捕获动态参数 ```javascript app.get('/users/:id', (req, res) => { console.log(req.params.id) // 输出 URL 中的动态参数 }) ``` - **中间件影响**:前置中间件可能修改请求对象或提前终止请求[^3]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值