错误:发送后无法设置标题,仅在刷新页面后发生
Posted
技术标签:
【中文标题】错误:发送后无法设置标题,仅在刷新页面后发生【英文标题】:Error: Can't set headers after they are sent , happen only after refreshing a page 【发布时间】:2015-03-24 19:18:26 【问题描述】:每次我在路由 'localhost:8080/' 刷新 html 页面或登录用户时,我都会收到此 错误:发送后无法设置标题。 据我所知发生此问题是由于意外调用了两次回调。该应用程序不会崩溃或发生任何事情,它只是在控制台上不断记录相同的错误。
这是代码。
var User = require('../models/user');
var Story = require('../models/story');
var jwt = require('jsonwebtoken');
var config = require('../../config');
var superSecret = config.secret;
module.exports = function(app, express)
// creating our first router
var apiRouter = express.Router();
// signup a user
apiRouter.post('/signup', function(req, res)
var user = new User(
name: req.body.name,
username: req.body.username,
password: req.body.password
);
user.save(function(err)
if(err) res.send(err);
res.json( message: 'User has been created!' );
);
);
apiRouter.get('/users', function(req, res)
User.find(, function(err, users)
if(err) res.send(err);
res.json(users);
);
);
// user login
apiRouter.post('/login', function(req, res)
User.findOne(
username: req.body.username
).select('name username password').exec(function(err, user)
if(err) throw err;
if(!user)
res.json( message: "Wrong User" );
else if(user)
var validPassword = user.comparePassword(req.body.password);
if(!validPassword)
res.json( message: "Invalid Password" );
else
var token = jwt.sign(
id: user._id,
name: user.name,
username: user.username
, superSecret,
expiresInMinute: 1440
);
// return all the sucess
res.json(
success: true,
message: "Successfully login and token created!" + token.name,
token: token
);
;
);
);
// write a middleware for login
// A middleware for login user only, once a user has logged in , he can enter other links below
apiRouter.use(function(req, res, next)
// do logging
console.log("Somebody just came to our app!");
var token = req.body.token || req.param('token') || req.headers['x-access-token'];
// check if token exist
if(token)
jwt.verify(token, superSecret, function(err, decoded)
if(err)
res.status(403).send( success: false, message: 'Failed to authenticate user' );
else
// if everything is good save request for use in other routes
req.decoded = decoded;
next();
);
else
res.status(403).send( success: false, message: 'No token provided' );
);
apiRouter.route('/')
.post(function(req, res)
var story = new Story(
user: req.decoded.id,
content: req.body.content
);
story.save(function(err, stor)
if(err) res.send(err)
console.log(stor);
res.json(stor);
);
)
.get(function(req, res)
Story.find( user: req.decoded.id , function(err, story)
if(err) res.send(err);
res.json(story);
);
);
apiRouter.get('/me', function(req, res)
res.send(req.decoded.name);
);
apiRouter.route('/:user_id')
.get(function(req, res)
User.findById(req.params.user_id, function(err, user)
if(err) res.send(err);
res.json(user);
);
)
.put(function(req, res)
User.findById(req.params.user_id, function(err, user)
if(err) res.send(err);
if(req.body.name)
user.name = req.body.name;
if(req.body.username)
user.username = req.body.username;
if(req.body.password)
user.password = req.body.password;
user.save(function(err)
if(err) res.send(err);
res.json( message: "User updated" );
);
);
);
return apiRouter;
【问题讨论】:
【参考方案1】:发生错误时,您发送了两次响应:
if (err) res.send(err);
res.json(foo);
替换为:
if (err) res.send(err); return;
res.json(foo);
【讨论】:
谢谢你的回答,但我不太明白为什么它会调用两次?因为 if err then send if not res.json? 因为大部分代码基本都是这样写的,需要把逻辑相同的代码全部改掉吗? 遗憾的是,这是回调地狱的最新技术。学会爱样板,包括if (err) done(err); return;
以上是关于错误:发送后无法设置标题,仅在刷新页面后发生的主要内容,如果未能解决你的问题,请参考以下文章