如何解决“将标头发送到客户端后无法设置标头”
Posted
技术标签:
【中文标题】如何解决“将标头发送到客户端后无法设置标头”【英文标题】:How can i resolve 'Cannot set headers after they are sent to the client' 【发布时间】:2019-02-28 19:20:30 【问题描述】:如何解决Cannot set headers after they are sent to the client
:
app.js
var express = require('express');
var session = require('express-session');
var mongoose = require('mongoose');
var app = express();
var ejs = require('ejs');
var port = 3000;
var bodyParser = require('body-parser');
var mongoDB = "mongodb://localhost:27017/vinavdb";
app.set('views', __dirname + '/admin') app.engine('html', ejs.renderFile);
app.set('view engine', 'ejs');
app.set('trust proxy', 1);
app.use(session(
secret: 'dsghbrtdfhbdfg64545TRYFFHGGJNN',
resave: false,
saveUninitialized: true
))
app.use(bodyParser.json());
app.use(bodyParser.urlencoded(
extended: true
));
var sess;
mongoose.Promise = global.Promise;
mongoose.connect(mongoDB,
useNewUrlParser: true
);
var nameSchema = new mongoose.Schema(
firstname: String,
lastname: String,
email: String,
password: String
);
var User = mongoose.model("User", nameSchema);
app.get("/", (req, res) =>
sess = req.session;
if (sess.email)
res.redirect("/admin");
else
res.sendFile(__dirname + "/index.html");
);
app.get("/login", (req, res) =>
res.sendFile(__dirname + "/login.html");
);
app.post("/addname", function(req, res)
var myData = new User(req.body);
User.findOne(
email: req.body.email
, function(err, resv)
if (resv == null)
myData.save().then(item =>
res.send("Name saved to database")
).catch(err =>
res.status(400).send("Unable to save to database");
);
res.send("ThankYou For your Registration")
else if (resv.email == req.body.email)
res.send("Email is already registered");
else
res.send("Srry data is not allowed");
);
);
app.post("/login", function(req, res, next)
User.findOne(
email: req.body.email
, function(err, vals)
if (vals == null)
res.end("Invalid Logins");
else if (vals.email == req.body.email && vals.password == req.body.password)
sess = req.session;
sess.email = req.body.email;
res.redirect('/admin');
else
res.send("Srry data is not allowed");
);
);
app.route('/admin').get(function(req, res, next)
sess = req.session;
if (sess.email)
res.send(__dirname + "/admin/index.html");
else
res.write('Please login first.');
)
app.listen(port, () =>
console.log("Server listening on port " + port);
);
【问题讨论】:
如果您想获得帮助,那么您至少应该花时间以可读的方式格式化代码。此外,您必须说明何时(针对哪条路线)发生此错误。 你必须放弃res.send("ThankYou For your Registration")
线。
当我添加 "res.send(__dirname + "/admin/index.html");"这一行。我收到“'在将标头发送到客户端后无法设置标头'”此错误消息
@AmitVerma User res.sendFile
而不是 res.send
因为您发送的是 html
文件而不是数据。
【参考方案1】:
您的错误原因:您正尝试将单个请求的响应发送两次。
一个请求有一个响应。
一旦发送响应,您就不能再次为同一个请求发送它。在您的/addname
API 中,您尝试发送响应两次。所以删除一个。
这里.save()
是异步函数,所以节点不会等待并执行
res.send("ThankYou For your Registration")
第一次和稍后保存记录后,它将尝试发送res.send("Name saved to database")
,因此您在这里遇到错误。
app.post("/addname", function(req, res)
var myData = new User(req.body);
User.findOne(
email: req.body.email
, function(err, resv)
if (resv == null)
myData.save().then(item =>
console.log("Name saved to database")
res.send("ThankYou For your Registration")
).catch(err =>
res.status(400).send("Unable to save to database");
);
else if (resv.email == req.body.email)
res.send("Email is already registered");
else
res.send("Srry data is not allowed");
);
);
【讨论】:
【参考方案2】:执行 res.send 后,您不能在同一个请求中再次调用它,它只允许每个请求一个响应。在您的代码中,我认为这部分可能会发生:
if (resv == null)
myData.save().then(item =>
res.send("Name saved to database")
).catch(err =>
res.status(400).send("Unable to save to database");
);
res.send("ThankYou For your Registration")
在这种情况下,如果您在保存 myData 时发送了一个响应,但您之前已经异步发送了另一个响应(“ThankYou For your Registration”)。
希望对你有帮助
【讨论】:
当我添加 "res.send(__dirname + "/admin/index.html");"这一行。我收到“'在将标头发送到客户端后无法设置标头'”此错误消息以上是关于如何解决“将标头发送到客户端后无法设置标头”的主要内容,如果未能解决你的问题,请参考以下文章
将标头发送到客户端后无法设置标头-请帮助我在代码中理解这一点
Node.js,Express:将标头发送到客户端后无法设置标头
Firebase 云功能错误:“在将标头发送到客户端后无法设置标头”