Node.js,Express:将标头发送到客户端后无法设置标头
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node.js,Express:将标头发送到客户端后无法设置标头相关的知识,希望对你有一定的参考价值。
首先,我阅读了所有其他StackOverflow答案和GitHub问题,但似乎都没有解决我的问题。使用以下代码(不建议使用其中的一些,脏代码表示抱歉):
var express = require('express');
var fs = require('fs');
var path = require('path');
var parser = require('body-parser');
//Initializing the Express Framework
const app = express();
const mongoose = require('mongoose');
const uuidv4 = require ('uuid/v4');
var jose = require('node-jose');
var secureRandom = require('secure-random');
var bcrypt = require('bcrypt');
const jwt = require('express-jwt');
const jwt2 = require('jsonwebtoken');
var userSchema = new mongoose.Schema(
username: type:String,unique:true,
password: String
,timestamps:true)
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
var signingKey = secureRandom(256, type: 'Buffer');
app.use(express.json());
app.use(express.urlencoded( extended: true ));
// Add headers
app.use(function (req, res, next)
res.removeHeader('X-Powered-By');
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,Authorization');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
);
var claims =
iss: "http://example.com/", // The URL of your service
sub: "users/admin1", // The UID of the user in your system
name: "User Name",
scope: "self, admins"
userSchema.pre('save', function (next)
var user = this;
if (!user.isModified('password')) return next();
bcrypt.hash(user.password,10).then((hashedPassword) =>
user.password = hashedPassword;
next();
)
, function (err)
next(err);
)
userSchema.methods.comparePassword=function(candidatePassword,next) bcrypt.compare(candidatePassword,this.password,function(err,isMatch)
if(err) return next(err);
next(null,isMatch)
)
module.exports = mongoose.model("user", userSchema);
function protectRoute(req,res,next)
// if user exists the token was sent with the request
if(req.user)
//if user exists then go to next middleware
next();
// token was not sent with request send error to user
else
res.status(500).json(error:'login is required');
/* app.get('/protected',
jwt(secret: 'shhhhhhared-secret'),
function(req, res)
if (!req.user.admin) return res.sendStatus(401);
res.sendStatus(200);
); */
MongoClient.connect(url,
useUnifiedTopology: true,
useNewUrlParser: true,
,function(err, db)
if (err) throw err;
var dbo = db.db("demo");
dbo.collection("demo").find().toArray(function(err, result)
if (err) throw err;
console.log(result);
db.close();
);
);
readJsonFile = function(fname, res)
fs.readFile(fname, 'utf8', function (err,data)
if (err)
console.log(err);
res.send(data.toString().replace(/\n|\r/g,''));
);
app.get('/', function (req, res)
res.send('Hello World!');
);
app.get('/users', function (req, res)
MongoClient.connect(url,
useUnifiedTopology: true,
useNewUrlParser: true,
,function(err, db)
if (err) throw err;
var dbo = db.db("demo");
dbo.collection("users").find().toArray(function(err, result)
if (err) throw err;
res.send(result);
db.close();
);
);
console.log("GET UserCollection from MongoDB");
);
app.post('/users/:id', verifyToken, function (req, res)
jwt2.verify(req.token, 'secretkey', (err, auth) =>
if(err)
res.sendStatus(403);
else
res.json(
message: 'User created (in theory)',
authData
)
)
res.json(
message: 'User created (in theory)2'
)
);
app.post('/api/login', function (req, res)
// Mock user TODO: implement proper BackEnd!
const user =
id:1,
username:'brad',
email: 'brad@gmail.com'
jwt2.sign(user, 'secretkey', expiresIn: '1h', (err, token) =>
res.json(
token
);
);
);
app.get('/user', function (req, res)
readJsonFile('user.json', res);
console.log("GET User");
);
// FORMAT OF TOKEN
// Authorization: Bearer <access_token>
// Verify Token
function verifyToken(req, res, next)
// Get auth header value
const bearerHeader = req.headers['authorization'];
// Check if bearer is undefined
if(typeof bearerHeader !== 'undefined')
// Split at the space
const bearer = bearerHeader.split(' ');
// Get token from array
const bearerToken = bearer[1];
// Set the token
req.token = bearerToken;
// Next middleware
next();
res.json(message: "Login successful");
else
// Forbidden
res.sendStatus(403);
next();
app.listen(3000, function ()
console.log('Listening on port 3000!');
);
if(process.env.NODE_ENV !== 'production')
process.once('uncaughtException', function(err)
console.error('FATAL: Uncaught exception.');
console.error(err.stack||err);
setTimeout(function()
process.exit(1);
, 100);
);
运行应用程序并发布URL / users / 5后,出现以下错误,应用程序崩溃:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:485:11)
at Array.write (C:\Users\User\Documents\Project\Project2\node_modules\finalhandler\index.js:285:9)
at listener (C:\Users\User\Documents\Project\Project2\node_modules\on-finished\index.js:169:15)
at onFinish (C:\Users\User\Documents\Project\Project2\node_modules\on-finished\index.js:100:5)
at callback (C:\Users\User\Documents\Project\Project2\node_modules\ee-first\index.js:55:10)
at IncomingMessage.onevent (C:\Users\User\Documents\Project\Project2\node_modules\ee-first\index.js:93:5)
at IncomingMessage.emit (events.js:215:7)
at endReadableNT (_stream_readable.js:1183:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21)
ReferenceError: authData is not defined
at C:\Users\User\Documents\Project\Project2\src\app.js:134:9
at C:\Users\User\Documents\Project\Project2\node_modules\jsonwebtoken\verify.js:223:12
at getSecret (C:\Users\User\Documents\Project\Project2\node_modules\jsonwebtoken\verify.js:90:14)
at Object.module.exports [as verify] (C:\Users\User\Documents\Project\Project2\node_modules\jsonwebtoken\verify.js:94:10)
at C:\Users\User\Documents\Project\Project2\src\app.js:127:8
at Layer.handle [as handle_request] (C:\Users\User\Documents\Project\Project2\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\User\Documents\Project\Project2\node_modules\express\lib\router\route.js:137:13)
at verifyToken (C:\Users\User\Documents\Project\Project2\src\app.js:178:5)
at Layer.handle [as handle_request] (C:\Users\User\Documents\Project\Project2\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\User\Documents\Project\Project2\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\User\Documents\Project\Project2\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\User\Documents\Project\Project2\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\User\Documents\Project\Project2\node_modules\express\lib\router\index.js:281:22
at param (C:\Users\User\Documents\Project\Project2\node_modules\express\lib\router\index.js:354:14)
at param (C:\Users\User\Documents\Project\Project2\node_modules\express\lib\router\index.js:365:14)
at Function.process_params (C:\Users\User\Documents\Project\Project2\node_modules\express\lib\router\index.js:410:3)
我尝试添加return和next语句无济于事。
P.S这有助于理解问题:
此错误发生在您之前发送响应,然后尝试再次发送响应时。为此,您必须检查是否有任何一段代码发送了两次响应。有时由于nodejs的异步行为而发生。有时,一个流程将进入事件循环,我们发送响应,完成后,将再次发送响应。因此,您可以使用回调或异步等待来等待执行。
答案
[您的代码在该时间尝试多次发送响应时,会发生此错误,这是您的工作后API代码
app.post('/users/:id', verifyToken, function (req, res)
jwt2.verify(req.token, 'secretkey', (err, auth) =>
if(err)
res.sendStatus(403);
else
res.json(
message: 'User created (in theory)',
authData
)
)
);
只需从该API中删除多余的响应代码
另一答案
在app.post('/users/:id'..)
中,您发送了两次响应。因此,由于响应已发送,因此您第二次收到错误。
以上是关于Node.js,Express:将标头发送到客户端后无法设置标头的主要内容,如果未能解决你的问题,请参考以下文章
Post Request express:发送到客户端后无法设置标头
错误[ERR_HTTP_HEADERS_SENT]:无法在将标头发送到客户端后设置标头 - Express + Request
将 set-cookie 标头发送到 node.js 中的重定向 url