Error: Can't set headers after they are sent
发布于 8 年前 作者 newonejoe 6891 次预览 最后一次回复是 8 年前 来自 问答
新手一名,遇到问题,困扰了一天了,帮忙看看是什么问题啊 直接上code html:
<table class="ui selectable celled table segment" id="tbEventMessage">
<thead>
<tr>
<th>Event ID</th>
<th>Precursor Id</th>
<th>DataItem Id</th>
<th>Zone Number</th>
<th>Condition Id</th>
<th>SubCondition Id</th>
<th>State</th>
<th>Active Time</th>
<th>Event Time</th>
<th>Severity</th>
<th>Threshold</th>
<th>Message</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot class="full-witdh">
<tr>
<th colspan="3">
<a class="ui right labeled icon button" href="/eventMessages/create">
<i class="user icon"></i>Add eventMessage
</a>
</th>
</tr>
</tfoot>
</table>
Javascript:
var messageTable = $('#tbEventMessage').DataTable({
ajax:{
url: "/eventMessages",
type: "get",
dataSrc: ""
},
columns : [
{data: 'EventID'},
{data: 'PrecursorId'},
{data: 'DataItemId'},
{data: 'ZoneNumber'},
{data: 'ConditionId'},
{data: 'SubConditionId'},
{data: 'State'},
{data: 'ActiveTime', render: function(data){
return data.replace(/T/, ' ').replace(/\..+/, '');
}
},
{data: 'EventTime', render: function(data){
return data.replace(/T/, ' ').replace(/\..+/, '');
}
},
{data: 'Severity'},
{data: 'Threshold'},
{data: 'Message'}
],
createdRow: function(row, data, index) {
var severity = data['Severity'];
if (severity >= 700) {
$('td',row).css('background-color', "crimson");
}else if(severity >= 400){
$('td',row).css('background-color', "#FA8072");
}else if (severity >= 100){
$('td',row).css('background-color', "coral");
}else{
$('td',row).css('background-color', "#4FC08D");
}
}
});
setTimeout(refresh, 1000);
function refresh() {
//ajax
messageTable.ajax.reload();
setTimeout(refresh, 1000);
}
model:
const sql = require('mssql');
var config = {
user: 'sa',
password: 'porta',
server: 'CN10LT099',
database: 'ClairAlarm',
pool: {
max: 10,
min: 0,
idleTimeoutMillis: 30000
}
};
module.exports = {
closeConnection: function closeConnection() {
sql.close();
},
getEventMessages: function getEventMessages(limit) {
//console.log(limit);
return new sql.ConnectionPool(config).connect().then(pool => {
// Query
return pool.request()
.input('recordlimit', sql.Int, parseInt(limit))
.execute('ReadEventMessage')
}).then(result => {
//pool.close();
return result.recordset;
}).catch(err => {
//pool.close();
console.trace(err);
});
}
};
eventMessages.js
var express = require('express');
var router = express.Router();
var EventMessageModel = require('../models/eventMessages');
var checkLogin = require('../middlewares/check.js').checkLogin;
// GET /eventMessages
router.get('/', function(req, res, next) {
EventMessageModel.getEventMessages(20)
.then(function(eventMessages) {
//console.dir(eventMessages);
//res.end(JSON.stringify(eventMessages));
res.json(eventMessages);
});
//.catch(next);
});
module.exports = router;13 回复
https://cnodejs.org/topic/53774ffecbcc396349ca1155
@2VCl1md 谢谢,我知道是这个相关的问题,就是找不到哪里错了啊,我这边用的是res.json(), 这个有问题吗?
@newonejoe 应该是吧,我之前也遇到过这个问题
我的问题好像和同一个页面的两个ajax有关系, 两个ajax会有冲突吗?我真的是个小白,帮我看看吧
</script>
很奇怪的情况,你可以试试改成res.send测试一下 这是res.json我查到的部分解释https://segmentfault.com/q/1010000009000325/a-1020000009003036 是否有可能是因为res.json最后的set导致的? 我觉得最起码两个Ajax不会冲突吧
跟ajax应该没关系,看起来也不像是res.json的问题,我猜应该是别的地方有个异步的end操作
@Yuki-Minakami 目前我修改了两个地方,现在没有这个报错了
把两个ajax都设置为同步的方式 async = false, 我过会儿再试一下打开会是怎样
在router中去掉了next,改为了
router.get(’/’, function(req, res) { EventMessageModel.getEventMessages(20) .then(function(eventMessages) { res.setHeader(‘Content-Type’, ‘application/json’); res.send(JSON.stringify(eventMessages)); return; }); });
@2linziyi2 谢谢你的回复,我发现两个Ajax在全部设置为异步的时候就发生冲突了,该怎么优化呢?两个Ajax都是放在setInterval里面用来读取实时数据,刷新highchart和datatable的
问题应该是在 then 里面 出现了异常,然后在 catch 中 又执行了 next,导致两次 writeHead 操作。。
你可以試一下
上面可能是我編程的風格,你可以應該在EventMessageModel前加return
@alphaXkiller 谢谢您的解释,对于middleware我的理解不够深刻,导致了前面遇到的问题,考虑到实时性,我现在转向用socket.io来实现这个功能,效果还不错
index.js
@newonejoe socket.io是用來处理实时数据交换,譬如是聊天室,股票数据呈现之类的。如果只是用于提交表格的话,socket.io可能会导致资源浪费
@alphaXkiller 我用socket.io个来推送warning/error 信息到HMI,实时性要求高一点, 表格只是显示的手段,没有数据提交