You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express post路由挂载表单重复提交校验中间件后无限加载如何修复

问题根因

你的代码存在4个核心问题,其中第一个直接导致首次提交无限加载:

  • 中间件未覆盖数据库无访客记录的场景:首次提交时Visitor.find({})返回空数组,for循环完全不会执行,中间件既没有返回响应也没有调用next(),请求一直挂起就会出现无限加载。
  • 数组遍历方式错误:用for...in遍历数组拿到的是数组索引字符串,而非访客记录对象,后续属性判断逻辑完全失效。
  • 条件判断逻辑错误:visitor.session === visitors.session中visitors是查询返回的整个数组,不存在session属性,判断条件永远不成立;且循环内只要第一个记录不匹配就直接调用next(),跳过了后续所有记录的校验,你现在的重复拦截功能实际是误打误撞生效的,存在严重漏洞。
  • 性能缺陷:全表查询所有访客记录做校验,数据量增大后接口性能会急剧下降。

修复方案

1. 重写校验中间件

直接按当前用户的sessionID查询数据库,避免全表扫描,同时覆盖所有分支的响应/next调用:

module.exports.isRevisit = async (req, res, next) => {
  // 直接按当前用户sessionID查询,性能更高逻辑更清晰
  const existVisitor = await Visitor.findOne({ session: req.sessionID });
  if (existVisitor) {
    // 已提交过,返回错误页
    return res.render("error", { redirectedVisitor: existVisitor });
  }
  // 未提交过,放行到后续路由逻辑
  next();
};

2. 可选优化路由逻辑

补充异常捕获,避免数据库操作报错导致请求挂起:

app.post("/home", isRevisit, async (req, res, next) => {
  try {
    const date = new Date();
    const today = date.getDate();
    const visitor = new Visitor({
      input: req.body.input,
      Date: today,
      session: req.sessionID,
    });

    await visitor.save();
    const goodVisitorsCount = await Visitor.count({ input: "good", Date: today });
    const badVisitorsCount = await Visitor.count({ input: "bad", Date: today });
    const allVisitorsCount = await Visitor.count({});
    res.render(`GoodOrBad/${req.body.input}`, {
      goodVisitorsCount,
      badVisitorsCount,
      allVisitorsCount,
    });
  } catch (err) {
    // 捕获异常传递给express错误处理中间件,避免请求挂起
    next(err);
  }
});

内容的提问来源于stack exchange,提问作者sultan.301

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 20:24:03