【问题标题】:how to send server response.cookie and response.render together?如何将服务器 response.cookie 和 response.render 一起发送?
【发布时间】:2018-05-25 17:25:11
【问题描述】:
app.get("/auth/google", passport.authenticate("google", {
    session: false,
    scope: ["profile", "email"]
}));

passport.use(new GoogleStrategy({
        clientID: " x",
        clientSecret: " y",
        callbackURL: "http://localhost:3000/auth/google/callback"
    },
    function(accessToken, refreshToken, Gprofile, done) {
        process.nextTick(function() {

            Gdata = {
                'id': Gprofile.id,
                'name': Gprofile.displayName,
                'profileImage': Gprofile.photos[0].value,
                'gender': Gprofile.gender,
                'email': Gprofile.emails[0].value
            };

            console.log('Gdata recieved');
            console.log('--------------------------------------------------------------------------');

            return done(null, true); //It seems redirects to failureRedirect or successRedirect.
        });
    }
));

app.get("/auth/google/callback", passport.authenticate('google', {
    session: false,
    failureRedirect: "/google_callback_fail",
    successRedirect: "/reports"
}));

app.get("/reports", function(req, res) {
    // ------------DB
    var db = require('../model/connection.js');
    var stmt;

    var name = Gdata.name.split(" ");
    stmt = "INSERT INTO User( `first_name`, `last_name`, `email`) VALUES (?,?,?)";


    var x = new Promise(function(resolve, reject) {
        var sentToCJS;
        db.query(stmt, [name[0], name[1], Gdata.email], function(err, rows) {
            if (err) reject(err);

            PAYLOAD = { userID: rows.insertId };

            ENCODED_JWT = _jwt.sign(PAYLOAD, 'secret', { expiresIn: EXP_TIME });
            console.log("1 ENCODED_JWT:", ENCODED_JWT);


            sentToCJS = {
                'jwt': ENCODED_JWT,
                'name': Gdata.name,
                'profileImage': Gdata.profileImage,
                'gender': Gdata.gender,
                'email': Gdata.email
            };
            console.log("sentToCJS:", sentToCJS);

            //creates persistant cookie.
               res.cookie("jwt", ENCODED_JWT, {
                maxAge: 604800, //7days to ms
                httpOnly: true,
                sameSite: true,
                signed: true //detects if user has modified the cookie
            });

            resolve(sentToCJS);
        });

    });

    x.then(function(sentToCJS) {
        res.render('reports', sentToCJS);
    });


    x.catch(function(error) {
        console.log("error", error);
    });

期望的结果:服务器响应 cookie 和渲染('reports', sentToCJS); res.cookie 和 res.render 需要工作。

错误:发送后无法设置标题。 在 SendStream.headersAlreadySent

如何将 res.cookie 和 res.render 一起发送或以多个响应发送? express 似乎不可能,但 node.js res.write 或 writeHead 方法可能。

【问题讨论】:

  • 这两个语句是单个响应的一部分。两次响应是什么意思?
  • @Muthukumar 我更新了错误信息

标签: node.js http express cookies response


【解决方案1】:

res.cookie() 只是将 cookie 与其他标头一起排队等待最终响应(它与 res.setHeader() 的操作类型相同),因此您显示的代码将同时发送 cookie 和渲染。它应该像你已经拥有的那样工作。

错误:发送后无法设置标头。在 SendStream.headers 已发送

既然您最近刚刚添加了您看到报告的这个特定错误,那么您的代码中还有其他事情发生。您在问题中显示的两个函数调用本身不会导致此错误。该错误通常是由请求处理程序中的某些异步操作处理不正确引起的。很有可能,您在异步操作完成之前调用res.render(),然后当异步操作完成时,您尝试发送标头,但为时已晚,因为您已经呈现了页面并发送了响应,您可以'每个请求发送的响应不超过一个。

为了帮助您修复代码,我们需要查看包含这两个函数调用的整个请求处理程序的代码,然后我们可能会帮助您进行正确的修复。在没有看到代码的情况下,我们只能说您在请求处理程序中处理异步操作的方式可能存在错误。

【讨论】:

  • @21wesd34eqwfsdv - 该错误消息不仅仅由您显示的代码行引起。它通常是由您在错误时间发送一部分响应的异步操作的处理方式错误引起的。我们需要查看此请求处理程序的所有代码,以显示您是否犯了该错误。但是,你这样一个接一个地显示的两个函数调用不会导致你自己说的错误。导致该错误还涉及其他代码。
  • @21wesd34eqwfsdv - 在我的回答中添加了我们现在知道的内容的摘要,直到您包含更多代码。
  • @jfriend00 添加了主要细节。并更新了我的问题。问题似乎是发送两个响应。
  • @Internal - 您是在此处发布原始问题的同一个人吗?如果是这样,您应该在以发布问题的同一用户身份登录时对其进行编辑。目前,该编辑正在等待批准,因为系统认为它是由原始问题编写者之外的其他人编辑的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-26
  • 2018-06-16
  • 1970-01-01
  • 2018-02-05
  • 1970-01-01
  • 2021-03-10
  • 1970-01-01
相关资源
最近更新 更多