Node.js: http.js:691 throw new Error('Can\'t set headers after they are sent.')

Posted

技术标签:

【中文标题】Node.js: http.js:691 throw new Error(\'Can\\\'t set headers after they are sent.\')【英文标题】:Node.js: http.js:691 throw new Error('Can\'t set headers after they are sent.')Node.js: http.js:691 throw new Error('Can\'t set headers after they are sent.') 【发布时间】:2014-02-22 22:41:03 【问题描述】:

您好,我正在使用 MEAN 堆栈制作简单的应用程序。我得到这个错误 http.js:691 throw new Error('Can\'t set headers after they are sent.')

代码如下: server.js

// set up
var express = require('express');
var app = express();
var mongoose = require('mongoose');

// mongodb connection and app configuration
mongoose.connect('mongodb://localhost/test');

app.configure(function () 
    app.use(express.static(__dirname + '/app'));
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
);

// define model
var Employee = mongoose.model('Employee', 
    firstName : String,
    lastName : String,
    photoUrl : String
);

// routes ==========================
// api
// GET
app.get('/api/employees', function(req, res) 
    console.log("GET");
    Employee.find(function(err, employees) 
        if(err) 
            res.send(err);
        

        res.json(employees);
    );
);

// Get by ID
app.get('/api/employees/:employeeId', function(req, res) 
    Employee.findById(req.params.employeeId, function(err, employee) 
        if(err) 
            res.send(err);
        

        res.json(employee);
    );
    Employee.find(function(err, employees) 
        if(err) 
            res.send(err);
        

        res.json(employees);
    );
);

// POST
app.post('/api/employees', function(req, res) 
    Employee.create(
        firstName : req.body.firstName,
        lastName : req.body.lastName,
        photoUrl : req.body.photoUrl
    , function(err, employee) 
        if(err) 
            res.send(err);
        
        Employee.find(function(err, employees)
            if(err) 
                res.send(err);
            
            res.json(employees);
        );
    );
);

// DELETE
app.delete('/api/employees/:employee_id', function(req, res) 
    Employee.remove(_id : req.params.employee_id, function (err, employee) 
        if(err) 
            res.send(err);
        

        Employee.find(function(err, employees) 
            if(err) 
                res.send(err);
            
            res.json(employees);
        )
    );
);

// application
app.get('*', function(req, res) 
    res.sendfile('./app/index.html'); 
);

// start listening (start app)
app.listen(8080);
console.log("App listening on port 8080");

还有: app.js Angular 路由

var employeesApp = angular.module('employeesApp', [
    'ngRoute',
    'EmployeesControllers',
    'employeeAppAnimations'
]);

employeesApp.config(['$routeProvider',
    function($routeProvider) 
        $routeProvider.
            when('/employees', 
                templateUrl: 'partials/employees_list.html',
                controller: 'EmployeesCtrl'
            ).
            when('/employees/:employeeId', 
                templateUrl: 'partials/employees_details.html',
                controller: 'EmployeeDetailsCtrl'
            ).
            otherwise(
                redirectTo: '/employees'
            );
    ]);

【问题讨论】:

【参考方案1】:

app.get('/api/employees/:employeeId', function() ...);

您正在使用 res.json 两次。让我们假设 Employee.findById 首先返回结果。那么,

res.json(employee)

已发送。然后代码稍微延迟进入 Employee.find 回调。这再次触发 res.json()。但由于对您的请求的响应已经发送,它无法对同一请求发送另一个响应。

这种情况会引发错误。

有两种方法可以解决这个问题。

    嵌套回调 - 在 Employee.findById 回调中调用 Employee.find。 在两个回调中添加条件以检查其他回调是否完成。然后发送一个响应。

【讨论】:

以上是关于Node.js: http.js:691 throw new Error('Can\'t set headers after they are sent.')的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL 如何在 node.js 中将服务器错误与客户端错误(最好使用 TryCatch 块)分开?

Node.js 入门

Node.js 模块

[Node.js]如何在IDEA中配置Node.js

node.js 初识node.js,运行在服务端的 JavaScript

node.js教程基础:node.js命令行选项