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

Express Validator 使用异步函数实现自定义校验的问题求解

express-validator 异步自定义校验实现方案

原代码核心问题

  • body() 等校验方法返回的是 Express 中间件函数,不能直接在路由处理函数内通过 await 调用,属于用法错误
  • custom() 校验器要求传入返回 Promise 的函数,原代码直接传入了 store.todoListTitleExists(title) 的执行结果(Promise 实例),不符合 API 要求
  • 路由处理函数未加 async 关键字,直接使用 await 会抛出语法错误
  • 缺少校验结果收集逻辑,无法提取错误信息用于 flash 展示

正确实现方式

你可以使用 express-validator 内置的 run() 方法手动在路由处理函数内执行校验链,完全满足你需要访问 res.locals.store 的需求:

// 需提前引入依赖
const { body, validationResult } = require('express-validator');

app.post("/lists/:todoListId/edit", 
  async (req, res) => {
    const store = res.locals.store;
    const todoListId = req.params.todoListId;

    // 手动执行校验链
    await body('todoListTitle')
      .trim()
      .isLength({ min: 1 })
      .withMessage("列表标题不能为空")
      .isLength({ max: 100 })
      .withMessage("列表标题不能超过100个字符")
      .custom(async (title) => {
        const titleExists = await store.todoListTitleExists(title);
        // 可选优化:编辑场景下排除当前列表本身的标题重复
        // const titleExists = await store.todoListTitleExists(title, todoListId);
        if (titleExists) {
          throw new Error('标题已存在');
        }
      })
      .run(req); // 传入请求对象手动触发校验

    // 收集校验错误
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      // 提取错误信息存入flash,跳转回编辑页
      req.flash('errors', errors.array().map(item => item.msg));
      return res.redirect(`/lists/${todoListId}/edit`);
    }

    // 校验通过后的业务逻辑
    // ...
})

关键说明

  • custom 内的异步函数抛出的错误会自动被识别为校验失败信息,通过 validationResult 统一收集
  • 所有校验错误可以一次性提取存入 flash,前端遍历展示即可

内容的提问来源于stack exchange,提问作者bugsyb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:06:04