发送后无法设置标题。:Raspbian Web服务器上的Sendgrid邮件响应

时间:2019-02-12 22:22:14

标签: node.js sendgrid

在发送带有sendgrid的电子邮件后呈现页面时出现问题。 该问题最有可能在下面的代码片段中:

  sgMail.send(msg, function(err, json) {
if (err) {
  return res.render('contactResponse', 
    {title: 'An error with sending the email has occured. Please try again later or contact me via LinkedIn'});
}

res.render('contactResponse', 
{title: 'Thank you for your email. I will respond as soon as possible.'});

});

现在在本地主机中,此代码可以正常运行。它会显示“谢谢您的电子邮件,并向我发送电子邮件。 然后,我将其上传到我的Raspberry服务器并启动。现在,它在控制台中给出以下错误: 错误:500-发送标头后无法设置标头。 -/联系-POST 并在屏幕上显示“发生电子邮件发送错误”。

现在我已经阅读了其他文章,这可能是在诸如res.render或res.send之类的方法中两次调用res.end的问题。我认为这可能是我在发送邮件后呈现响应屏幕的问题。我不确定是否是这样,它可以在localhost上运行,所以我不完全理解为什么它在我的服务器上表现奇怪。

现在,我愿意提出有关如何在没有此错误的情况下使用“谢谢”或“发生错误”进行响应的建议。也可能是我代码中的其他原因。有关完整代码,请参见this pastebin

1 个答案:

答案 0 :(得分:1)

您的router.post('/', function(req, res, next) {...}函数中有多个可以调用res.render()的位置,但是其余部分的执行继续,因此可以再次调用res.render(),这是导致错误的原因。错误:“发送标头后无法发送”。每个请求只能发送一个响应。之后,Express识别出这是一个错误,并记录该特定错误消息。

因此,基本上,您使用的是代码风格:

if (some condition) {
    return res.render()
} 

// more code here

仅在if()位于某个异步回调内部之前起作用。一旦完成,return仅从异步回调中返回,而不会停止其余外部函数的执行。相反,您需要将if语句嵌套在异步回调中。

这是您遇到问题的一种情况:

request(verificationUrl, function(error, response, body) {
    body = JSON.parse(body);
    // Success will be true or false depending upon captcha validation.
    if (body.success !== undefined && !body.success) {
        // this return ONLY returns from the request() callback, not from the
        // request handler, thus the rest of the request handler continues to
        // execute
        return res.render('contact', {
            title: "Let's talk!",
            name: req.body.name,
            email: req.body.email,
            subject: req.body.subject,
            content: req.body.content,
            errs: [{
                msg: "Failed captcha verification, try again."
            }]
        });
    }
});

// more code continues here, will allow multiple calls to res.render()
// to happen if the above one got called

return res.sender()位于request()回调内部,因此那里的return不会从app.post()返回,它只会从request()回调返回,然后功能体的执行继续。您可能需要做的是使用更多的if/else和更多的嵌套,这样当您的代码在执行的一个分支中失败时,就不会在其他执行中继续。

例如,解决此特定问题的一种方法是将另一个放置在request()处理程序中,如下所示:

request(verificationUrl, function(error, response, body) {
    body = JSON.parse(body);
    // Success will be true or false depending upon captcha validation.
    if (body.success !== undefined && !body.success) {
        return res.render('contact', {
            title: "Let's talk!",
            name: req.body.name,
            email: req.body.email,
            subject: req.body.subject,
            content: req.body.content,
            errs: [{
                msg: "Failed captcha verification, try again."
            }]
        });
    } else {
        // rest of function body continues here
    }
});

// no more function body code here
  

现在在本地主机中,此代码可以正常工作

逻辑显然是错误的。如果可行,那仅仅是因为您通过异步计时或通过if逻辑的特殊流程而碰运气而感到非常幸运。必须固定逻辑以可靠且重复地工作。