将标头发送到客户端后无法设置标头/服务器在页面刷新时崩溃

Posted

技术标签:

【中文标题】将标头发送到客户端后无法设置标头/服务器在页面刷新时崩溃【英文标题】:Cannot set headers after they are sent to the client/ Server crashes with this when page refreshes 【发布时间】:2021-12-26 12:25:06 【问题描述】:

几天前在这里提出了一个问题,以为我已经弄清楚了,甚至接受了答案,因为无论如何它都是正确的。但现在我有同样的问题,同样的错误。

这是错误。

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:558:11)
    at ServerResponse.header (/Users/apple/Documents/Web Dev/collab/Backend/node_modules/express/lib/response.js:771:10)
    at ServerResponse.send (/Users/apple/Documents/Web Dev/collab/Backend/node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/Users/apple/Documents/Web Dev/collab/Backend/node_modules/express/lib/response.js:267:15)
    at /Users/apple/Documents/Web Dev/collab/Backend/routes/index.js:90:23
    at processTicksAndRejections (internal/process/task_queues.js:93:5) 
  code: 'ERR_HTTP_HEADERS_SENT'

Heres Index.js。第 90 行在最底部, @router.get("/", isAuth, (req, res)

const router = require("express").Router();
const passport = require("passport");
const bodyParser = require("body-parser");
const genPassword = require("../lib/passwordUtils").genPassword;
const connection = require("../config/database");
const mongoose = require("mongoose");
const User = mongoose.models.User;
const isAuth = require("./authMiddleware").isAuth;
// cors is needed with router.use else you have to put routes on the app.js
const cors = require("cors");
router.use(cors( origin: "http://localhost:3001", credentials: true ));
// const isAdmin = require("./authMiddleware").isAdmin;
router.use(bodyParser.urlencoded( extended: false ));

/**
 * -------------- Post ROUTES ----------------
 *
 */

router.post("/login", (req, res, next) => 
  passport.authenticate("local", (err, user, info) => 
    if (err) 
      throw err;
     else if (!user) 
      res.send("No User Exists");
     else 
      req.logIn(user, (err) => 
        if (err) throw err;
        res.send(user);
        return;
        // console.log(req.user);
      );
    
  )(req, res, next);
);

router.post("/register", (req, res) => 
  const saltHash = genPassword(req.body.repeatPassword);

  const salt = saltHash.salt;
  const hash = saltHash.hash;

  const newUser = new User(
    username: req.body.firstInput,
    fName: "",
    lName: "",
    title: "",
    hash: hash,
    salt: salt,
  );

  newUser.save().then((user) => );
  res.sendStatus(200);
);

/**
 * -------------- GET ROUTES ----------------
 *
 */

router.post("/user", (req, res) => 
  const fName = req.body.firstInput;
  const lName = req.body.secondInput;

  const title = req.body.repeatPassword;

  const user = req.session.passport.user;
  User.updateOne(
     _id: user ,
     fName: fName, lName: lName, title: title ,
    function (err, result) 
      if (err) 
        res.sendStatus(401);
        console.log(err);
       else 
        res.sendStatus(200);
      
    
  );
);
router.get("/", isAuth, (req, res) => 
  const userMap = ;
  User.find(, function (err, users) 
    users.forEach(function (user) 
      userMap[user._id] = user;
    );
    return userMap;
  )
    .then((response) => 
      res.status(200).json( user: req.user, auth: true, response );
      return;
    )
    .catch((err) => console.log(err));
);

module.exports = router;

Heres App.js

const express = require("express");
const app = express();
const mongoose = require("mongoose");
const session = require("express-session");
const passport = require("passport");
const crypto = require("crypto");
const routes = require("./routes");
const isAuth = require("./routes/authMiddleware").isAuth;
const connection = require("./config/database");
const cors = require("cors");
app.use(cors( origin: "http://localhost:3001", credentials: true ));
const User = mongoose.models.User;

const bodyParser = require("body-parser");

const MongoStore = require("connect-mongo")(session);

require("dotenv").config();

app.use(express.json());
// app.use(bodyParser.urlencoded( extended: false ));

app.use(express.urlencoded( extended: true ));

const sessionStore = new MongoStore(
  mongooseConnection: mongoose.connection,
  collection: "sessions",
);

app.use(
  session(
    secret: "zdfbdaf",
    resave: true,
    saveUninitialized: true,
    store: sessionStore,
    cookie: 
      cookie:  secure: false ,
      maxAge: 1000 * 60 * 60 * 24,
    ,
  )
);

require("./config/passport");

app.use(passport.initialize());
app.use(passport.session());

app.use("/", routes);

app.listen(3000);

这里是 authMiddleware.js

module.exports.isAuth = (req, res, next) => 
  if (req.isAuthenticated()) 
    next();
    // res.status(200).json( user: req.user, auth: true );
   else 
    res.status(401).json( auth: false );
  
;

// module.exports.isAdmin = (req, res, next) => 
//     if (req.isAuthenticated() && req.user.admin) 
//         next();
//      else 
//         res.status(401).json( msg: 'You are not authorized to view this resource because you are not an admin.' );
//     
// 

这里是passport.js

const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const connection = require("./database");
const mongoose = require("mongoose");
const User = mongoose.models.User;
const validPassword = require("../lib/passwordUtils").validPassword;
const cors = require("cors");
passport.use(cors( origin: "http://localhost:3001" ));

const customFields = 
  usernameField: "username",
  passwordField: "password",
;

passport.use(
  new LocalStrategy(customFields, (username, password, done) => 
    User.findOne( username: username )
      .then((user) => 
        if (!user) 
          console.log("No user");
          return done(null, false);
         else 
          const isValid = validPassword(password, user.hash, user.salt);
          if (isValid) 
            console.log("Logged in");

            return done(null, user);
           else 
            console.log("Wrong Password");
            return done(null, true);
          
        
      )
      .catch((err) => 
        done(err);
      );
  )
);

passport.serializeUser((user, done) => 
  done(null, user.id);
);

passport.deserializeUser((id, done) => 
  User.findById(id, (err, user) => 
    done(err, user);
  )
    .then((user) => 
      done(null, user);
    )
    .catch((err) => done(err));
);

它只有一半的时间崩溃,是吗?它起初有效,直到您刷新页面。我很茫然。不和谐的人也不知道这个问题。我在这里乞求一些帮助。我快疯了。

【问题讨论】:

你确定这是 authMiddleware.js 文件吗 哦,拍得好。我猜我的复制和粘贴搞砸了。谢谢 【参考方案1】:

这是因为您在找到用户后调用 done 两次 第二个是 .then 阻止 passport.deserializeUser 函数

这将起作用:

passport.deserializeUser((id, done) => 
  User.findById(id, (err, user) => 
      done(err, user)   
  );
);

【讨论】:

你是我的英雄。非常感谢。

以上是关于将标头发送到客户端后无法设置标头/服务器在页面刷新时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

将标头发送到客户端后无法设置标头-请帮助我在代码中理解这一点

为啥我在 Nodejs 中收到“无法在将标头发送到客户端后设置标头”错误?

如何解决“将标头发送到客户端后无法设置标头”

将标头发送到客户端后无法设置标头-Nodejs + AWS-S3 getObject

GraphQL 突变“在将标头发送到客户端后无法设置标头”

Firebase 云功能错误:“在将标头发送到客户端后无法设置标头”