返回

揭秘 Express-Validator 中验证链条失效的谜团:新手与资深程序员的救星

javascript

揭秘 Express-Validator 中验证链条失效的谜团

引言

在 Express.js 中使用 Express-Validator 进行表单验证时,开发人员有时会遇到一个恼人的错误:"Cannot set headers after they are sent to the client."。这个错误会让新手程序员抓狂,而资深程序员也会感到困惑。在这篇文章中,我们将深入探讨导致此错误的根源,并提供一个简单的解决方案,帮助你恢复 Express-Validator 的验证链条功能。

问题根源:响应已发送

此错误的根本原因在于 Express-Validator 的验证链条在中间件中执行,而中间件在路由处理程序之前执行。这意味着,如果你在验证链条中设置标头,然后在处理程序中再次发送响应,就会发生冲突。这是因为,一旦响应被发送,就无法再修改标头。

解决方案:移动标头设置

要解决这个问题,我们需要将标头设置代码从验证链条移动到处理程序中。这样,当验证链条运行时,标头不会被设置,从而避免冲突。

// 移动到处理程序
router.post("/", async (req, res) => {
  const result = validationResult(req);
  if (result.isEmpty()) {
    // 设置标头
    res.setHeader("Content-Type", "application/json");
  }

  res.send({ errors: result.array() });
});

示例代码(已修正)

const express = require("express");
const router = express.Router();
const User = require("../Models/User");
const { body, validationResult } = require("express-validator");

//post route for registering user(No auth required)
router.post(
  "/",
  [
    body("name", "Name cannot be empty")
      .notEmpty()
      .customSanitizer(value => {
        return escape(value);
      }),
    body("email", "Enter a valid email").isEmail(),
    body(
      "password",
      "Password must be 8characters long. 1 lowercase, 1 uppercase, 2 number and 1 special character is required"
    ).isStrongPassword({
      minLength: 8,
      minLowercase: 1,
      minUppercase: 1,
      minNumbers: 1,
      minSymbols: 1,
    }),
  ],
  async (req, res) => {
    const result = validationResult(req);
    if (result.isEmpty()) {
      //All validations passed
      try {
        const user = User(req.body);
        await user.save();
        res.setHeader("Content-Type", "application/json");
        res.send(req.body);
      } catch (err) {
        return res.status(400).json({ error: "Email already exists" });
      }
    }
    res.send({ errors: result.array() });
  }
);

module.exports = router;

总结

通过将标头设置代码移动到处理程序中,我们避免了 Express-Validator 验证链条和处理程序之间的冲突。这确保了验证链条能够正常运行,并防止了 "Cannot set headers after they are sent to the client." 错误。

常见问题解答

问:为什么我的验证链条不起作用?

答: 验证链条可能不起作用的原因有很多。最常见的原因是标头设置代码放在了错误的位置。其他可能的原因包括:

  • 验证规则不正确
  • 没有将 validationResult 应用于请求对象
  • 验证链条中存在其他错误

问:如何调试 Express-Validator 中的错误?

答: 要调试 Express-Validator 中的错误,可以检查以下内容:

  • 验证规则是否正确
  • 标头设置代码是否放在正确的位置
  • 验证链条中是否存在其他错误

问:我可以在验证链条中设置什么类型的标头?

答: 在验证链条中,你可以设置任何类型的标头。但是,最常见的是设置 Content-Type 标头。

问:为什么需要自定义标头?

答: 你可能需要自定义标头来实现各种目的,例如:

  • 指定响应内容的类型
  • 设置缓存控制策略
  • 添加安全标头

问:Express-Validator 与其他验证库有何不同?

答: Express-Validator 与其他验证库的不同之处在于它针对 Express.js 框架量身定制。这使得它易于与 Express.js 一起使用,并提供了一系列针对 Express.js 特定需求量身定制的功能。