遇到一个很诡异的 Nodejs bug,关于 routes 的

遇到一个很诡异的 Nodejs bug,关于 routes 的

用的 express

项目结构是这么回事,其实就是个模拟登录:

  • agent
    • dom_agent.js

传入 url ,账户,密码三个参数,来获取 html

  • parser
    • a.js
    • b.js

传入 url ,账户,密码三个参数,转发给 dom_agent.js ,然后解析各个类型的 html ,并且按照定义好的格式返回字典( JSON )

  • routes
    • a.js
    • b.js

var router = express.Router(); router.get 来定义路由,转发请求给 parser ,

很诡异的问题就是,明明请求的 a 路由, parser a 打印出来的 url 也是正确的,最后返回的数据格式也是正确的,就是数据不对,数据是另外一个网址的

这还不是最诡异的,最诡异的是,低频率测试的时候,都是没问题的(比如上线前的本地测试),一到生产环境,如果持续请求一个 url ,过不了几次,返回的数据就变成了其余 url 的,而且不固定,不固定啊不固定,不固定啊不固定😂

数据格式对,就是内容完全混乱

已经排查过的有:

开始我以为是没有 return 掉,所以接着执行了,哪个快就返回哪个,所以

  • 每个 callback ,前面都加上 return

但是发现没用,再一想,根本不是哪个快就返回哪个,因为数据格式是对的,请求的肯定是对应的路由,所以才能发给对应的 parser ,并没有往下执行

然后我怀疑是模块的缓存,查查资料,说 Node.js 的模块缓存是用来提高加载速度,貌似没关系

再有可能就是传入的参数,也就是那个 url 参数,被缓存了,但是貌似也不对,因为帐号密码没缓存(并没有发现返回其余用户的数据,只是返回自己其余 url 的数据)

也可能跟代码风格有关,我现在写法是

  • 每个文件第一行都 'use strict';
  • 每个 callback 前都加上 return
  • 每个 res.xx 前都加上 return
  • 几乎所有情况都是用的单引号
  • 貌似是没了,有的话再补充

5 回复

对了还要补充几个问题,每个 parser ,里面的方法名,是一样的,不知道这样会不会有影响


感觉是 dom_agent.js 的问题,这个是不是一个类?每次有 new 吗?

能把代码贴出来看下么?

贴出来略多。。怕大家懒得看嘛,就自己总结了下问题,项目在 GitHub 上放着呢~

对!!我已经解决这个问题了,就是在 dom_agent.js 里面

是全局变量的问题, target 变量不小心搞成全局的了,导致每个用户都会修改这个参数,所以也就导致了刚才的诡异

遇到关于 Node.js routes 的诡异 bug 通常与路径匹配、中间件顺序或异步代码处理不当有关。以下是一些常见的排查步骤和示例代码,希望能帮助你定位问题:

  1. 检查路径匹配: 确保你的路由路径正确无误,没有拼写错误。例如:

    const express = require('express');
    const app = express();
    
    app.get('/example', (req, res) => {
      res.send('Hello, World!');
    });
    
    app.listen(3000, () => {
      console.log('Server is running on port 3000');
    });
    
  2. 中间件顺序: 确保中间件按正确顺序应用。例如,如果你的某个中间件终止了请求响应,那么后面的路由将不会被执行。

    app.use((req, res, next) => {
      console.log('Middleware executed');
      next();
    });
    
  3. 异步代码: 如果你在路由处理函数中使用了异步操作(如数据库查询),确保正确处理了异步逻辑。

    app.get('/async-example', async (req, res) => {
      try {
        // 模拟异步操作
        await new Promise(resolve => setTimeout(resolve, 1000));
        res.send('Async operation completed');
      } catch (error) {
        res.status(500).send('Error: ' + error.message);
      }
    });
    
  4. 调试: 使用 console.log 或更高级的调试工具(如 Node.js 内置的调试器或 Visual Studio Code 的调试功能)来跟踪请求的处理流程。

如果以上步骤仍未解决问题,建议提供更详细的错误信息和代码片段,以便进一步分析。

回到顶部