express-session Error: Can't send headers after they are sent

孤人 提交于 2021-01-07 02:52:20

问题


I am using express-session to prevent variable from being global for more than one client, so they don't get tangled up. Here is my entire NEW express code:

const path = require("path");
const bodyParser = require("body-parser");
const express = require("express");
const app = express();
const session = require('express-session');

app.use(session({
  secret: process.env.SECRET,
  name: 'lastQuestion',
  cookie: {
    sameSite: "lax",
    secure: true,
    httpOnly: true
  }
}));

app.use(bodyParser.urlencoded({ extended: false }));
app.set('views', __dirname + '/public');
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');

app.get('/', (req, res) => {
  req.session.lastQuestion = generateQuestion();
    res.render(__dirname + '/public/index.html', {response: "Hello!", question: req.session.lastQuestion, instructions: true});
});

app.listen(process.env.PORT);

app.post("/prompt", (req, res) => {
    console.log("New prompt: " + req.body.inputOne);
  req.session.lastQuestion = generateQuestion();
    res.render(__dirname + '/public/index.html', {response: evaluatePrompt(req.body.inputOne.toLowerCase()), question: req.session.lastQuestion, instructions: false});
});

app.post("/answer", (req, res) => {
    console.log("New answer: " + req.body.inputTwo);
  console.log(req.body.question + req.session.lastQuestion);
  analyzeConversationAndWriteToLTM(req.session.lastQuestion, req.body.inputTwo);
  //Line above this /\ /\ /\ /\
  req.session.lastQuestion = generateQuestion();
    res.render(__dirname + '/public/index.html', {response: "Hello!", question: req.session.lastQuestion, instructions: false});
});

app.post("/regenerate", (req, res) => {
  req.session.lastQuestion = generateQuestion();
    res.render(__dirname + '/public/index.html', {response: "Hello!", question: req.session.lastQuestion, instructions: false});
});

entire OLD code:

3     const bodyParser = require("body-parser");
1414      const express = require("express");
1515      const app = express();
1616      const session = require('express-session');
17  - var lastQuestion;
1817     
1918      app.use(session({
2019        secret: process.env.SECRET,
21  -   name: 'session',
20  +   name: 'lastQuestion',
2221        cookie: {
23  -     sameSite: false,
22  +     sameSite: "lax",
2423          secure: true,
2524          httpOnly: true
2625        }
2726      }));
@@ -31,34 +30,31 @@
3130      app.engine('html', require('ejs').renderFile);
3231      app.set('view engine', 'html');
3332     
3433      app.get('/', (req, res) => {
35  -     res.sendFile(__dirname + '/public/index.html');
36  -   lastQuestion = generateQuestion();
34  +   req.session.lastQuestion = generateQuestion();
35  +     res.render(__dirname + '/public/index.html', {response: "Hello!", question: req.session.lastQuestion, instructions: true});
37  -     res.render(__dirname + '/public/index.html', {response: "Hello!", question: lastQuestion, instructions: true});
3836      });
3937     
4038      app.listen(process.env.PORT);
4139     
4240      app.post("/prompt", (req, res) => {
4341          console.log("New prompt: " + req.body.inputOne);
44  -     res.sendFile(path.join(__dirname + '/public/index.html'));
45  -   lastQuestion = generateQuestion();
42  +   req.session.lastQuestion = generateQuestion();
43  +     res.render(__dirname + '/public/index.html', {response: evaluatePrompt(req.body.inputOne.toLowerCase()), question: req.session.lastQuestion, instructions: false});
46  -     //res.render(__dirname + '/public/index.html', {response: evaluatePrompt(req.body.inputOne.toLowerCase()), question: lastQuestion, instructions: false});
4744      });
4845     
4946      app.post("/answer", (req, res) => {
5047          console.log("New answer: " + req.body.inputTwo);
51  
     res.sendFile(path.join(__dirname + '/public/index.html'));
52     console.log(req.body.question + lastQuestion);
53    analyzeConversationAndWriteToLTM(lastQuestion, req.body.inputTwo);
54     lastQuestion = generateQuestion();
48     console.log(req.body.question + req.session.lastQuestion);
49   analyzeConversationAndWriteToLTM(req.session.lastQuestion, req.body.inputTwo);
50     req.session.lastQuestion = generateQuestion();
51     res.render(__dirname + '/public/index.html', {response: "Hello!", question: req.session.lastQuestion, instructions: false});
55  -     res.render(__dirname + '/public/index.html', {response: "Hello!", question: lastQuestion, instructions: false});
5652      });
5753     
5854      app.post("/regenerate", (req, res) => {
59  -   lastQuestion = generateQuestion();
60  -     res.render(__dirname + '/public/index.html', {response: "Hello!", question: lastQuestion, instructions: false});
55   req.session.lastQuestion = generateQuestion();
56     res.render(__dirname + '/public/index.html', {response: "Hello!", question: req.session.lastQuestion, instructions: false});
6157      });

And analyzeConversationAndWriteToLTM:

function analyzeConversationAndWriteToLTM(unrefinedFirstStatement, unrefinedSecondStatement){
  updateLTMArrays();
  var firstStatement = unrefinedFirstStatement.toLowerCase().replace(punctuation,"");
  var secondStatement = unrefinedSecondStatement.toLowerCase().replace(punctuation,"");
  if(prompts.includes(firstStatement) || secondStatement == "new question" || secondStatement == "newquestion" || secondStatement == "" || secondStatement == " " || firstStatement == "" || firstStatement == " "){
    return;
  } else {
    if(!filter.isProfane(firstStatement) && !filter.isProfane(secondStatement)){
      var finalFirstStatement = firstStatement;
      var finalSecondStatement = capitalizeFirstLetter(unrefinedSecondStatement);
      writeStatementToLTM(finalFirstStatement, finalSecondStatement);
      updateLTMArrays();
      console.clear();
    } else {
      console.log("Rude!");
    }
  }
}

/answer is the one that remembers the session.lastQuestion cookie. Anyways, even though I'm using cookies, session.lastQuestion is updated for every client when one client updates it, resulting in desyncing.


回答1:


You can't call both res.sendFile() and res.render() in the same request handler - pick one or the other. Both are trying to send a response to the incoming http request, but you only get to send one response per request. This is why you get the warning from Express "Can't set headers after they are sent." because when you go to send the second response, it sees that a response has already been sent and it encounters that when it tries to send the headers for the 2nd response.

If you think about it logically, the browser is making a request and will then display the response. Once it gets a response, the request is done. It is not expecting you to send yet another response and, in fact, Express won't allow you to send another response (thus why you get the warning you do).



来源:https://stackoverflow.com/questions/65544373/express-session-error-cant-send-headers-after-they-are-sent

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!