发送到客户端后无法设置标头
Posted
技术标签:
【中文标题】发送到客户端后无法设置标头【英文标题】:Cannot set headers after they are sent to the client 【发布时间】:2018-05-25 00:34:57 【问题描述】:标头发送到客户端后无法设置。这是身份验证发布请求后我的后端错误。看起来有问题 标题。我很抱歉我的项目的脏代码我需要做其他事情,所以评论中有一些代码。 这是我的代码
const express = require("express");
const router = express.Router();
const Spec = require("../models/specialist");
const jwt = require("jsonwebtoken");
const config = require("../config/data");
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
router.get("/login",(req,res)=>
res.render("login");
);
router.get("/signup",(req,res)=>
res.render("signup");
);
//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:"User",
isActive:true,
created:date,
updatedToken:"JWT"
);
Spec.addUser(newUser,(err,user)=>
if(err)
console.log("err");
else
res.header("Content-Type","application/json");
// res.redirect("/users/login");
);
);
// passport.use(new LocalStrategy(
// function(username, password, done)
// Spec.getUser(username, function(err, user)
// if(err) return console.error(err.stack);
// if(!user)
// return done(null, false, message: 'Unknown User');
//
// Spec.comparePassword(password, user.password, function(err, isMatch)
// if(err) return console.error(err.stack);
// if(isMatch)
// return done(null, user);
// else
// return done(null, false, message: 'Invalid password');
//
// );
// );
// ));
// passport.serializeUser(function(user, done)
// done(null, user.id);
// );
// passport.deserializeUser(function(id, done)
// User.getUserById(id, function(err, user)
// done(err, user);
// );
// );
//Authentication route
router.post('/spec/authenticate', (req, res,next) =>
const email = req.body.email;
const password = req.body.password;
Spec.getUser(email, (err, user) =>
if(err) throw err;
if(!user)
return res.json(success: false, msg: 'User not found');
Spec.comparePassword(password, user.password, (err, isMatch) =>
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
)
Spec.saveToken(email,token,(err,success)=>
if(err) return err;
console.log("Success");
// res.setHeader('Authorization','bearer '+token );
res.cookie('Authorization','bearer '+token);
res.json ( success: true, token: 'bearer ' + token );
res.redirect("/users/user");
);
else
return res.json(success: false, msg: 'Wrong password');
);
);
// res.redirect("/user");
);
router.get("/user",passport.authenticate('jwt',session:false), (req,res)=>
res.render("user");
);
router.get("/forgotPass",(req,res)=>
res.render("forgotPass");
);
router.get("/we",(req,res)=>
res.render("we");
);
module.exports = router;
你可以在我的代码中找到其他错误,因为我尝试了很多不同的方法。这里是 passport.js 配置文件
const JwtStrategy = require('passport-jwt').Strategy,
ExtractJwt = require('passport-jwt').ExtractJwt;
const config = require("./data");
const mongoose = require("mongoose");
const User = require("../models/specialist");
module.exports = function(passport)
let cookieExtractor = function(req)
var token = null;
if (req && req.cookies)
token = req.cookies['Authorization'];
return token;
;
let opts =
opts.jwtFromRequest = cookieExtractor;
opts.secretOrKey = config.JWT_SECRET;
passport.use(new JwtStrategy(opts, function(jwt_payload, done)
User.findOne(name:jwt_payload._doc.name, function(err, user)
if (err)
console.log(err);
return done(err, false);
if (user)
console.log("OK 200");
return done(null, user);
else
console.log("no user");
return done(null, false);
// or you could create a new account
);
));
// // Google OAuth Strategy
// passport.use('googleToken', new GooglePlusTokenStrategy(
// clientID: config.oauth.google.clientID,
// clientSecret: config.oauth.google.clientSecret
// , async (accessToken, refreshToken, profile, done) =>
// try
// // Should have full user profile over here
// console.log('profile', profile);
// console.log('accessToken', accessToken);
// console.log('refreshToken', refreshToken);
// const existingUser = await User.findOne( "google.id": profile.id );
// if (existingUser)
// return done(null, existingUser);
//
// const newUser = new User(
// method: 'google',
// google:
// id: profile.id,
// email: profile.emails[0].value
//
// );
// await newUser.save();
// done(null, newUser);
// catch(error)
// done(error, false, error.message);
//
// ));
// passport.use('facebookToken', new FacebookTokenStrategy(
// clientID: config.oauth.facebook.clientID,
// clientSecret: config.oauth.facebook.clientSecret
// , async (accessToken, refreshToken, profile, done) =>
// try
// console.log('profile', profile);
// console.log('accessToken', accessToken);
// console.log('refreshToken', refreshToken);
// const existingUser = await User.findOne( "facebook.id": profile.id );
// if (existingUser)
// return done(null, existingUser);
//
// const newUser = new User(
// method: 'facebook',
// facebook:
// id: profile.id,
// email: profile.emails[0].value
//
// );
// await newUser.save();
// done(null, newUser);
// catch(error)
// done(error, false, error.message);
//
// ));
// LOCAL STRATEGY
// module.exports = function(passport)
// passport.use(new LocalStrategy(
// function(username, password, done)
// Spec.findOne( username: username , function (err, user)
// if (err) return done(err);
// if (!user) return done(null, false);
// if (!user.verifyPassword(password)) return done(null, false);
// return done(null, user);
// );
//
// ));
//
这是认证的ajax请求
$('.logInForm').on('submit', function (e)
$.ajax(
type: 'post',
url: 'http://localhost:3000/users/spec/authenticate',
data: $(this).serialize(),
success:function(data)
console.log(data);
localStorage.setItem("authToken",data.token);
).done(function(data)
if(data.token)
location.href="http://localhost:3000/users/user";
else
console.log("err");
);
e.preventDefault();
);
非常感谢。
【问题讨论】:
哪个特定操作给您带来了错误? 出现该错误的身份验证后响应 Error: Can't set headers after they are sent to the client的可能重复 【参考方案1】:这是由于您的代码尝试从身份验证函数发送多个响应。
res.json ( success: true, token: 'bearer ' + token ); // 1st Response
res.redirect("/users/user"); // 2nd Response
删除其中一个您不使用的。
【讨论】:
以上是关于发送到客户端后无法设置标头的主要内容,如果未能解决你的问题,请参考以下文章
NodeJS "发送到客户端 NodeJS 后无法设置标头"
Post Request express:发送到客户端后无法设置标头