发送后无法设置标头 - 通过 NodeJs 发布新用户
Posted
技术标签:
【中文标题】发送后无法设置标头 - 通过 NodeJs 发布新用户【英文标题】:Can't set headers after they are sent - Posting new Users through NodeJs 【发布时间】:2016-10-04 14:23:19 【问题描述】:我正在尝试使用 Google Maps API、NodeJs、Express、MongoDB 构建应用程序, Mongoose 和 AngularJS,我在查看其他相关 SO Q/A 时遇到了无法解决的问题。
基本上,我试图将post
加入我的数据库用户,这些用户由username
和[latitude, longitude]
识别,他们提交了我认为的某种表单。
当我尝试直接从 Postman 等应用程序post
用户时,一切正常,我可以在我的数据库中看到新用户。
当我尝试在用户提交时直接发布用户时,我的 控制台 中出现以下错误:
/node_modules/mongodb-core/lib/topologies/server.js:766
catch(err) process.nextTick(function() throw err);
^
Error: Can't set headers after they are sent.
然后在我的 Google Chrome 控制台中登录:
angular.js:10695 GET http://localhost:3000/users net::ERR_CONNECTION_REFUSED
这是我的观点:
<form name="addForm" novalidate>
<div class="form-group">
<label for="username">Username
<span class="badge">All fields required</span>
</label>
<input type="text" class="form-control" id="username"
placeholder="OldandGold" ng-model="formData.username" required>
</div>
<div class="form-group">
<label for="latitude">Latitude</label>
<input type="text" class="form-control" id="latitude"
value="39.500" ng-model="formData.latitude" readonly>
</div>
<div class="form-group">
<label for="longitude">Longitude</label>
<input type="text" class="form-control" id="longitude"
value="-98.350" ng-model="formData.longitude" readonly>
</div>
<button type="submit" class="btn btn-danger btn-block"
ng-click="createUser()" ng-disabled="addForm.$invalid">Submit</button>
</form>
这是我的架构:
// Pulls Mongoose dependency for creating schemas
var mongoose = require('mongoose');
var GeoJSON = require('geojson');
var Schema = mongoose.Schema;
var LocationSchema = new Schema(
name: type: String, required: true,
location:
type: type : String, required: true,
coordinates : [Schema.Types.Mixed]
,
created_at: type: Date, default: Date.now,
updated_at: type: Date, default: Date.now
);
// Sets the created_at parameter equal to the current time
LocationSchema.pre('save', function(next)
now = new Date();
this.updated_at = now;
if(!this.created_at)
this.created_at = now
next();
);
// Indexes this schema in 2dsphere format (critical for running proximity searches)
LocationSchema.index(location: '2dsphere');
module.exports = mongoose.model('mean-locations', LocationSchema);
这是我的控制器的 createUser 函数:
$scope.createUser = function($rootScope, $on)
// Grabs all of the text box fields
var userData =
name: $scope.formData.username,
location:
type: "Point",
coordinates: [$scope.formData.latitude,
$scope.formData.longitude]
;
console.log(JSON.stringify(userData));
// Saves the user data to the db
$http.post('/users', userData)
.success(function(data)
// Once complete, clear the form (except location)
$scope.formData.username = "";
)
.error(function(data)
console.log('Error: ' + data);
);
;
最后,这是我的路线:
app.get('/users', function(req, res)
// Uses Mongoose schema to run the search (empty conditions)
var query = User.find();
query.exec(function(err, users)
if (err)
res.send(err);
// If no errors are found, it responds with a JSON of all users
res.json(users);
);
);
// POST Routes
// --------------------------------------------------------
// Provides method for saving new users in the db
app.post('/users', function(req, res)
// Creates a new User based on the Mongoose schema and the post body
var newuser = new User(req.body);
// New User is saved in the db.
newuser.save(function(err)
if (err)
res.send(err);
// If no errors are found, it responds with a JSON of the new user
res.json(req.body);
);
);
使用我的 Stringify Log
我可以看到正确的 json:
"name":"MyPoint","location":"type":"Point","coordinates":["50.064","16.260"]
我对 NodeJs 还很陌生,我不明白为什么会这样。
是什么原因造成的?我该如何解决这个问题?
提前致谢。
【问题讨论】:
【参考方案1】:问题就在这里,如果出现错误,你必须停止执行。 (注意退货)。例如,如果出现错误,您的代码将发送(res.send)错误并继续执行res.json()
,它将以您提到的错误结束,因为您已经设置了标头并发送了响应。
newuser.save(function(err)
if (err)
return res.send(err);
// If no errors are found, it responds with a JSON of the new user
res.json(req.body);
);
【讨论】:
感谢您的回答。我不再收到错误消息,但似乎没有将新创建的用户保存到数据库中。有什么想法吗? 尝试记录错误。如果出现错误,用户将不会被保存。你也必须为 app.get('/users', ...); 做同样的事情; 完全没有错误。当我使用邮递员发布同一用户时,一切正常。 嗯。在那种情况下,它可能是由您的角度代码引起的问题,我不是很熟悉。我建议您针对该问题提出一个新问题。【参考方案2】:“错误:发送后无法设置标头。”错误通常表示您正在发送多个响应(使用 express)。
例如,此代码将(尝试)发送两个响应以防出错
app.get('/users', function(req, res)
// Uses Mongoose schema to run the search (empty conditions)
var query = User.find();
query.exec(function(err, users)
if (err)
res.send(err); // first response
// If no errors are found, it responds with a JSON of all users
res.json(users); // second response
);
);
要解决此问题,请确保在发送响应后退出:
app.get('/users', function(req, res)
// Uses Mongoose schema to run the search (empty conditions)
var query = User.find();
query.exec(function(err, users)
if (err)
res.send(err);
return; // return here!
// If no errors are found, it responds with a JSON of all users
res.json(users);
);
);
【讨论】:
感谢您的回答。我不再收到错误消息,但似乎没有将新创建的用户保存到数据库中。有什么想法吗? 你能尝试缩小错误范围吗...也许在 post user 处理程序中喷洒 console.log 看这里***.com/questions/37633218/…以上是关于发送后无法设置标头 - 通过 NodeJs 发布新用户的主要内容,如果未能解决你的问题,请参考以下文章
UnhandledPromiseRejectionWarning:错误:发送后无法设置标头[重复]
为啥我在 Nodejs 中收到“无法在将标头发送到客户端后设置标头”错误?