异步处理导致的Can\'t set headers after they are sent??
发布于 4 年前 作者 CommanderXL 13724 次浏览 最后一次编辑是 3 年前 来自 问答

暂时没找到问题的所在。

	app.post('/chart', function(req, res){
				var SQL = 'xxxxxxx';
				connection.query(SQL, function(err, rows){
					res.send(rows);
				})
		})

如果这样写的话会报错: Can’t set headers after they are sent;

如果是写成 :

app.post('/chart', function(req, res){
	var SQL = 'xxxxxxxxxx';
	connection.query(SQL, function(err), rows){
			xxxxxxx
	};
	res.send({status:  0 });
})

这样是不会报错的。- -

前面的代码都没返回数据给前台的。

完整的代码:

var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
//var server = http.createServer(app);
http.listen(10086);

app.use(bodyParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static(path.join(__dirname, 'app')));   //设置静态目录

app.use(function (req, res, next) {
    res.sendFile(path.join(__dirname, '/app/index.html'));
    return next();
});

app.all('*', function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By", ' 3.2.1');
    res.header("Content-Type", "application/json;charset=utf-8");
    return next();
});

io.on('connection', function (socket) {
    console.log("some");
})

//接受子进程发送数据
wk.on('message', function (msg) {
    //所有客户端接收数据
    console.log(msg);
    io.sockets.emit('test', msg)
});

app.post('/', function (req, res) {
    //将数据传给子进程
    wk.send(req.body);
    //返回客户端数据
    return res.send(
        {
            status: 0,
            de: '123'
        }
    );
});

app.post('/chart', function (req, res) {
    var id, item, table, mapTable, mapQuery, sql;
    switch (req.body.day) {
        'xxxxxxx'
    }
    switch (req.body.area) {
        'xxxxxxxx'
    }
    switch (req.body.item) {
        'xxxxxxxxx'
    }

    sql = 'select time, id, ' + item + ' from ' + table + ', ' + mapTable + ' where  moistureinfo.ID = sensormap.sensorid and loggerid = ' + id;

    connection.query(sql, function (err, rows) {
       if(err){
           console.error(err);
           return ;
       }
        res.send({
            status: 0,
            data: rows
        });
    })
});

如果我把res.send()放在connection.query()后面,是能向前台返回数据的

13 回复

有大神帮忙解决下吗?

在别的地方有返回吧。你的代码不全,看不出问题。

说两点吧:1. 异常没有处理 2. 代码不全,同@leapon 看不出问题所在

肯定是app.js后面还有流程

肯定还有地方做了res.send()或者是多次callback了

app.use(function (req, res, next) {
    res.sendFile(path.join(__dirname, '/app/index.html'));
    return next();
});

app.all('*', function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By", ' 3.2.1');
    res.header("Content-Type", "application/json;charset=utf-8");
    return next();
});

这个是怎么回事?完全不对啊。这样一来,每个请求都会先发送 index.htm ,然后再发标头?然后再根据url再返回对应router的内容?太魔性了吧!

你肯定在顺序执行时已经执行了res.send();然后等到sql查完又执行一次res.send(),这样就导致了一个请求响应两次(就是你报的那个错)。 解决方案:要么不等sql返回就res.send(),要么把res.send()写到sql的异步回调中(阻塞等待返回)。

请去掉sendfile

楼主 异步处理导致的Can’t set headers after they are sent?? 这个问题解决了吗? 我现在也遇到了,方便的话,提供一下解决办法: 我的qq号:707041669

  1. 不要在多个处理中返回response。 当一次请求已经响应结束了,你又去调用res对象,肯定报错了。
  2. sendFile 的使用,为什么在那里 sendFile
回到顶部