将标头发送到客户端后无法设置标头/服务器在页面刷新时崩溃
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 中收到“无法在将标头发送到客户端后设置标头”错误?