NodeJS "发送到客户端 NodeJS 后无法设置标头"

Posted

技术标签:

【中文标题】NodeJS "发送到客户端 NodeJS 后无法设置标头"【英文标题】:NodeJS "Cannot set headers after they are sent to the client NodeJS"NodeJS "发送到客户端 NodeJS 后无法设置标头" 【发布时间】:2022-01-11 05:29:33 【问题描述】:

我在这里做错了什么? 我收到“错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端 NodeJS 后无法设置标头”,有人可以帮我吗?

我正在使用:

快递 猫鼬(用于 MongoDB)

控制器

export const postResetPasswordEmail: Controller = async (req: Request, res: Response, next: NextFunction): Promise<void> => 
   const  email  = req.body
   try 
      const errors: IValidatorError = getValidationErrors(req)
      if (Object.keys(errors).length !== 0) 
         res.status(403).json( errors )
         return
      
      const user = await User.findOne( email )
      if (!user) 
         res.status(404).json( message: AuthenticationErrors.noEmailFound )
         return
       else 
         if (!(user.passwordUpdatedAt === undefined || (new Date(user.passwordUpdatedAt) < new Date()))) 
            res.status(404).json( message: AuthenticationErrors.error10MinutesPassword )
            return
         
      
      const token = generateJWT( email , JWTKEY, '10m')
      await sendResetPasswordMail(email, token, next)
      res.status(200)
         .json( message: SuccessMessages.resetPassword )
    catch (err: any) 
      catchError(err, next)
   

发送重置密码邮件

const sendResetPasswordMail: SendResetPasswordMail = async (userEmail: string, token: string, next: NextFunction): Promise<void> => 
   try 
      const transporter = nodemailer.createTransport(
         service: 'gmail',
         auth: 
            user: adminEmail.email,
            pass: adminEmail.pass
         
      )
      const mailOptions = 
         from: adminEmail.email,
         to: userEmail,
         subject: 'Reset password',
         text: `Reset password: http://localhost:3000/resetPassword?token=$token`
      
      await transporter.sendMail(mailOptions)
    catch (err: any) 
      catchError(err, next)
   

生成JWT

const generateJWT: GenerateJWT = (userInfo: IUserInfo, JWTKEY: string, expireTime: string): string =>
   jwt.sign( ...userInfo , JWTKEY,  expiresIn: expireTime )

【问题讨论】:

你能告诉我怎么做吗? 哪个请求会出现该错误?请展示从请求开始到结束的所有代码,以便我们跟踪正在处理的请求的整个路径。 catchError() 是做什么的? 我从控制器收到此错误。在其他的末尾。 (行) const catchError: CatchError = (error: any, next: NextFunction): void =&gt; !error.statusCode ? error.statusCode = 500 : null next(error) 【参考方案1】:

我在 sendResetPasswordMail 中发现了一个缺陷: 假设你有一个异常,它在 sendResetPasswordMail catch 块中调用 catchError,在这种情况下,它会间接调用 next,而后者又会调用默认快速错误处理程序中的 res.status().send()。

尽管如此,尽管有异常 sendResetPasswordMail 会将控制权返回给您的控制器,该控制器将尝试在此之后发送状态 200,如果到那时错误处理程序已经发送了响应,您将收到错误消息。

有效的行为是不捕获 sendResetPasswordMail 中的异常并将其留给调用者。您还可以从 sendResetPasswordMail

中删除 next 参数

【讨论】:

以上是关于NodeJS "发送到客户端 NodeJS 后无法设置标头"的主要内容,如果未能解决你的问题,请参考以下文章

windows系统下简单nodej.s环境配置 安装

NodeJ中的密码术(SHA-1?)

本地 CSS 或 JS 的 MIME 类型错误阻止在使用 NodeJ 时加载自定义样式

如何使用 NodeJS 下载 pdf 并将其发送到客户端?

从服务器发送数据到客户端Nodejs

NodeJS如何将数据发送到一个特定的客户端