错误:发送后无法设置标头。
Posted
技术标签:
【中文标题】错误:发送后无法设置标头。【英文标题】:Error: Can't set headers after they are sent. 【发布时间】:2018-06-08 05:57:09 【问题描述】:我讨厌这个问题,因为得到了很多次,我虽然发现我的错误,但我错了。 好的,这是我的代码。
const mongoose = require ("mongoose");
const Spec = require("./specialist");
const Person = require("./person");
const Company = require("./company");
const bcrypt = require("bcryptjs");
module.exports.findUser=function(username,callback)
let query = email_num:username;
Spec.findOne(query,(err_spec,spec_user)=>
if(err_spec) throw err_spec;
if(!spec_user)
Person.findOne(query,(err_person,person_user)=>
if(err_person) throw err_person;
if(!person_user)
Company.findOne(query,(err_company,company_user)=>
if(err_company) throw err_company;
if(!company_user)
return console.log("Error User Not Found");
return callback(null,company_user);
);
return callback(null,person_user);
);
return callback(null,spec_user);
);
;
module.exports.comparePassword = function(candidatePassword, hash, callback)
bcrypt.compare(candidatePassword, hash, (err, isMatch) =>
if(err) throw err;
callback(null, isMatch);
);
;
module.exports.saveToken = function(username,role,token,callback)
let query = email_num:username;
let updateToken=updatedToken:token;
if(role==="Person-User")
Person.findOneAndUpdate(query,updateToken,callback);
else if(role==="Specialist-User")
Spec.findOneAndUpdate(query,updateToken,callback);
else if(role==="Company-User")
Company.findOneAndUpdate(query,updateToken,callback);
else
console.log("Something went goes wrong");
我创建了 3 个集合和这个文件来处理它们。 这是我的主要服务器代码。
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const cors = require("cors");
const handlebars = require("express-handlebars");
const app = express();
const passport = require('passport');
const cookieParser = require("cookie-parser");
const config = require("./config/data");
const routes = require("./routes/users");
const company = require("./routes/company");
const person = require("./routes/person");
mongoose.Promise = global.Promise;
let options =
useMongoClient: true,
reconnectTries: Number.MAX_VALUE,
reconnectInterval: 500,
poolSize: 10,
bufferMaxEntries: 0
;
mongoose.connect(config.database,options);
let db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function()
console.log( `DB connected $new Date()...`);
);
//app.set('views',__dirname+'views');
app.engine('handlebars', handlebars(defaultLayout:false));
app.set('view engine', 'handlebars');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded( extended: false ));
app.use(express.static(__dirname + '/public'));
// app.use(cors());
app.use(cookieParser());
// Passport Middleware
// require('./config/passport')(passport);
app.use(passport.initialize());
app.use(passport.session());
app.get("/",(req,res)=>
res.render("index");
);
// app.get("/forgotPass",(req,res)=>
// res.render("forgotPass");
// );
app.get("/user", (req,res)=>
res.render("user");
);
app.get("/login",(req,res)=>
res.render("login");
);
app.get("/signup",(req,res)=>
res.render("signup");
);
app.get("/we",(req,res)=>
res.render("we");
);
app.get("/blog",(req,res)=>
res.render("blog");
);
app.get("/contactUs",(req,res)=>
res.render("contactUs");
);
app.get("/userAsApplicant",(req,res)=>
res.render("userAsApplicant");
);
app.use("/users",routes);
app.use("/company",company);
app.use("/person",person);
app.get("/faq",(req,res)=>
res.render("faq");
);
app.listen(config.port,()=>
console.log(`Server running on port $config.port....`);
);
对于许多表单处理程序,我使用 Ajax 处理所有请求。
$(function ()
$('.subForm').on('submit', function (e)
$.ajax(
type: 'post',
url: 'http://localhost:3000/users/spec/register',
data: $(this).serialize(),
success:function(data)
if(data.success)
location.href="http://localhost:3000/login"
else
location.href="http://localhost:3000/signup"
);
e.preventDefault();
);
$('.personAuth').on('submit', function (e)
$.ajax(
type: 'post',
url: 'http://localhost:3000/person/register',
data: $(this).serialize(),
success:function(data)
if(data.success)
location.href="http://localhost:3000/login"
else
console.log("Chexav");
location.href="http://localhost:3000/signup";
);
e.preventDefault();
);
$('.companyAuth').on('submit', function (e)
$.ajax(
type: 'post',
url: 'http://localhost:3000/company/register',
data: $(this).serialize(),
success:function(data)
if(data.success)
location.href="http://localhost:3000/login"
else
location.href="http://localhost:3000/signup"
);
e.preventDefault();
);
$('.logInForm').on('submit', function (e)
$.ajax(
type: 'post',
url: 'http://localhost:3000/users/authenticate',
data: $(this).serialize(),
success:function(data)
console.log(data);
if(data.token)
localStorage.setItem("Authorization",data.token);
$.ajax(
type:'get',
url:'http://localhost:3000/users/user',
beforeSend: function(xhr)xhr.setRequestHeader('auth', localStorage.getItem("Authorization"));,
success:location.href="http://localhost:3000/users/user"
)
);
e.preventDefault();
);
);
还有这条用于身份验证的路由。
const express = require("express");
const router = express.Router();
const Spec = require("../models/specialist");
const jwt = require("jsonwebtoken");
const config = require("../config/data");
const Model = require("../models/model");
//Registration route
router.post("/spec/register",(req,res)=>
let date=new Date();
let newUser = new Spec(
name:req.body.spec_name,
email_num:req.body.spec_email,
password:req.body.spec_password,
role:"Specialist-User",
isActive:true,
created:date,
updatedToken:"JWT"
);
if(newUser.password===req.body.spec_confirmPass)
Spec.getUser(newUser.email_num,(error,user)=>
if(error) throw error;
if(!user)
Spec.addUser(newUser,(err,user)=>
if(err)
console.log("err");
res.json(success:false,msg:"Somethings Went Wrong");
else
res.header("Content-Type","application/json");
res.json(success:true,msg:"User Registered");
// res.redirect("/login");
);
else
res.json(success:false,msg:"User Already Exists");
);
else
res.json(success:false,msg:"Password Not Confirmed");
);
//Authentication route
router.post('/authenticate', (req, res,next) =>
const email = req.body.email;
const password = req.body.password;
console.log("UserData");
Model.findUser(email, (err, user) =>
console.log("UserData1");
if(err) throw err;
if(!user)
return res.json(success: false, msg: 'User not found');
Model.comparePassword(password, user.password, (err, isMatch) =>
console.log("UserData2");
if(err) throw err;
if(isMatch)
let payload=
name:user.name,
email:user.email_num,
role:user.role,
deleted:user.deleted,
isActive:user.isActive,
created:user.created,
;
let token = jwt.sign(payload,config.JWT_SECRET,
expiresIn:1440
);
Model.saveToken(email,user.role,token,(err,success)=>
if(err) return err;
console.log("Success");
// res.setHeader('Authorization',token);
// res.cookie('Authorization',token);
res.json ( success: true, token: token );
// res.redirect("/users/user");
);
else
return res.json(success: false, msg: 'Wrong password');
);
);
// res.redirect("/user");
);
router.use(function(req, res, next)
console.log(req.headers);
let token = req.body.token || req.headers['auth'] || req.query.token || req.cookies.Authorization;
// console.log(token);
if (token)
jwt.verify(token, config.JWT_SECRET, function(err, decoded)
if (err)
console.log(err);
return res.json( success: false, message: 'Failed to authenticate token.' );
else
req.decoded = decoded;
next();
res.render("user");
);
else
return res.status(403).json(
success: false,
message: 'No token provided.'
);
);
router.get("/user", (req,res)=>
res.render("user");
);
module.exports = router;
作为模板引擎,我使用的是 Handlebars。所以注册一切正常,但是当我尝试对服务器进行身份验证时会带来
我知道我可以使用 cookie,但我想远离它。 抱歉语言错误,感谢您的帮助。
【问题讨论】:
【参考方案1】:错误:发送后无法设置标头。
这意味着您正在向客户端发送多个响应。
我认为您只需要像这样在最后一个中间件中删除您的res.render("user");
:
router.use(function(req, res, next)
console.log(req.headers);
let token = req.body.token || req.headers['auth'] || req.query.token || req.cookies.Authorization;
// console.log(token);
if (token)
jwt.verify(token, config.JWT_SECRET, function(err, decoded)
if (err)
console.log(err);
return res.json( success: false, message: 'Failed to authenticate token.' );
else
req.decoded = decoded;
// Go next and delete res
next();
// res.render("user");
);
else
return res.status(403).json(
success: false,
message: 'No token provided.'
);
);
希望对你有帮助。
【讨论】:
这些都是 Ctrl+C 和 Ctrl+V 效果。非常感谢您非常快速有效的回答。))))))))))))))我会检查正确的。以上是关于错误:发送后无法设置标头。的主要内容,如果未能解决你的问题,请参考以下文章