Nodejs /reg注册页面部门代码重复执行问题(node-开发指南中)
Nodejs /reg注册页面部门代码重复执行问题(node-开发指南中)
按照nodejs开发指南中的代码,发布微博等功能已经开发完成,回头运行注册等页面,其中127.0.0.1:8000/reg(post)页面中部分代码会重复执行,并且服务器报错。
报错信息如下: events.js:72 throw er; // Unhandled ‘error’ event ^ Error: Can’t set headers after they are sent. at ServerResponse.OutgoingMessage.setHeader (http.js:692:11) at ServerResponse.res.setHeader (/home/cplatform/node/node-0.10.19/webapp/microblog/node_modules/express/node_modules/connect/lib/patch.js:59:22) at ServerResponse.res.set.res.header (/home/cplatform/node/node-0.10.19/webapp/microblog/node_modules/express/lib/response.js:527:10) at ServerResponse.res.location (/home/cplatform/node/node-0.10.19/webapp/microblog/node_modules/express/lib/response.js:661:8) at ServerResponse.res.redirect (/home/cplatform/node/node-0.10.19/webapp/microblog/node_modules/express/lib/response.js:703:8) at /home/cplatform/node/node-0.10.19/webapp/microblog/routes/index.js:84:5 at /home/cplatform/node/node-0.10.19/webapp/microblog/node_modules/user.js:31:3 at /home/cplatform/node/node-0.10.19/webapp/microblog/node_modules/mongodb/lib/mongodb/collection.js:347:9 at Server.Base._callHandler (/home/cplatform/node/node-0.10.19/webapp/microblog/node_modules/mongodb/lib/mongodb/connection/base.js:382:41) at /home/cplatform/node/node-0.10.19/webapp/microblog/node_modules/mongodb/lib/mongodb/connection/server.js:472:18
/routes/index.js 中/reg代码如下: app.post(’/reg’, checkNotLogin); app.post(’/reg’,function(req,res){ if(req.body[‘password-repeat’] != req.body[‘password’]){ req.flash(‘error’,‘两次输入的口令不一致’); return res.redirect(’/reg’); } var md5 =crypto.createHash(‘md5’); var password = md5.update(req.body.password).digest(‘base64’);
var newUser = new User({ name: req.body.username, password:password, }); User.get(newUser.name, function(err, user){ if(user) err = ‘Username already exists.’; if(err){ req.flash(‘error’, err); return res.redirect(’/reg’); } newUser.save(function(err){ if(err){ req.flash(‘error’, err); return res.redirect(’/reg’); } console.log(‘jjjjjjjjjjjj’); req.session.user = newUser; console.log(req.session.user); req.flash(‘success’, ‘reg success’) res.redirect(’/’); }); }); });
其中运行两次的部分为: jjjjjjjjjjjj { name: ‘rr’, password: ‘UU8bQ59AT4b3cJD6ntyWzg==’ } POST /reg 302 16ms - 68b jjjjjjjjjjjj { name: ‘rr’, password: ‘UU8bQ59AT4b3cJD6ntyWzg==’ }
百思不得其姐,求各位大神指点迷津
Node.js /reg 注册页面代码重复执行问题
问题描述
在实现一个基于 Node.js 的微博应用时,根据开发指南中的代码,发布微博等功能已经开发完成。但在运行注册页面时(127.0.0.1:8000/reg
),发现部分代码会重复执行,并且服务器报错。
报错信息
events.js:72
throw er; // Unhandled ‘error’ event
^
Error: Can’t set headers after they are sent.
问题分析
错误信息表明 Can't set headers after they are sent
,这通常是因为响应已经被发送后尝试再次设置响应头或发送响应。从代码来看,问题可能出在 res.redirect('/reg')
被多次调用。
示例代码
以下是 /routes/index.js
文件中的 /reg
路由代码:
const express = require('express');
const app = express();
const crypto = require('crypto');
const User = require('./models/User'); // 假设 User 模型在这里定义
const flash = require('connect-flash');
// 中间件检查是否已登录
function checkNotLogin(req, res, next) {
if (req.session.user) {
return res.redirect('/');
}
next();
}
app.use(flash());
app.post('/reg', checkNotLogin);
app.post('/reg', function(req, res) {
if (req.body['password-repeat'] !== req.body['password']) {
req.flash('error', '两次输入的口令不一致');
return res.redirect('/reg');
}
const md5 = crypto.createHash('md5');
const password = md5.update(req.body.password).digest('base64');
const newUser = new User({
name: req.body.username,
password: password,
});
User.get(newUser.name, function(err, user) {
if (user) {
err = 'Username already exists.';
}
if (err) {
req.flash('error', err);
return res.redirect('/reg');
}
newUser.save(function(err) {
if (err) {
req.flash('error', err);
return res.redirect('/reg');
}
console.log('jjjjjjjjjjjj');
req.session.user = newUser;
console.log(req.session.user);
req.flash('success', '注册成功');
res.redirect('/');
});
});
});
module.exports = app;
解决方案
- 确保中间件顺序正确:将
checkNotLogin
中间件放在路由处理函数之前。 - 避免多次重定向:确保在每次响应发送后不再调用
res.redirect
或其他设置响应的方法。
总结
通过调整中间件顺序和确保响应只发送一次,可以解决 Can't set headers after they are sent
的问题。上述代码展示了如何正确处理用户注册逻辑并避免重复执行问题。
用 node 0.6 + express 1.x 试试看,版本问题。
有可能。。书里的代码都是老版本的样式。。
但是路由指向,代码都应该是正确的。怎么会执行两次,奇怪。。
顶。。。
貌似在学习这个N-blog的第一章的时候,都有这个问题
根据你提供的错误信息和代码片段,问题在于路由处理函数被多次调用,导致响应头多次设置。具体来说,在 /reg
路由处理中,checkNotLogin
函数被两次注册到同一个路由上,这会导致中间件和实际处理逻辑都被执行两次。
示例代码修正
首先,确保路由只注册一次:
app.post('/reg', checkNotLogin, function(req, res) {
if (req.body['password-repeat'] !== req.body['password']) {
req.flash('error', '两次输入的口令不一致');
return res.redirect('/reg');
}
var md5 = crypto.createHash('md5');
var password = md5.update(req.body.password).digest('base64');
var newUser = new User({
name: req.body.username,
password: password,
});
User.get(newUser.name, function(err, user) {
if (user) {
err = 'Username already exists.';
}
if (err) {
req.flash('error', err);
return res.redirect('/reg');
}
newUser.save(function(err) {
if (err) {
req.flash('error', err);
return res.redirect('/reg');
}
console.log('jjjjjjjjjjjj');
req.session.user = newUser;
console.log(req.session.user);
req.flash('success', 'reg success');
res.redirect('/');
});
});
});
详细解释
-
路由注册:确保
app.post('/reg', checkNotLogin)
只注册一次。在你的代码中,checkNotLogin
被注册了两次,导致中间件和实际处理逻辑被多次执行。 -
错误处理:每次响应之前检查是否有错误,如果有错误则返回重定向并结束请求处理流程。
-
密码哈希:使用
crypto.createHash
对密码进行哈希处理,并存储其base64
编码形式。 -
用户查找与保存:查找数据库中是否存在相同用户名的用户,如果存在则返回错误信息;否则保存新用户并设置会话信息。
通过以上修改,可以避免重复执行问题,并解决 Can’t set headers after they are sent
错误。