html5 - EventSource报错
问题描述
错误
Error: Can’t set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:357:11)at ServerResponse.header (D:nodejavascript-demonode_modulesexpresslibresponse.js:730:10)at ServerResponse.send (D:nodejavascript-demonode_modulesexpresslibresponse.js:170:12)at Timeout.setInterval [as _onTimeout] (D:nodejavascript-demorouteseventsourceeventsource.js:8:8)at ontimeout (timers.js:384:18)at tryOnTimeout (timers.js:244:5)at Timer.listOnTimeout (timers.js:214:5) Program node --debug ./bin/www exited with code 1
const express = require(’express’);const router = express.Router();router.get(’/connect’,function(req,resp,next){ resp.append(’Content-Type’,’text/event-stream’); console.log(req.method); setInterval((data)=>{resp.send(’hello!’); },1000,’hello’);});router.get(’/html’,(req,resp,next)=>{ resp.render(’./eventsource/msgsend_recevie.html’);});module.exports=router;
<!DOCTYPE html><html lang='en'><head> <title>EventSource消息发送</title> <style type='text/css'>*{ margin:0 auto; padding:0;}p{ width:440px; height:450px; border:2px solid; margin-top:100px;}</style></head><body> <p><textarea rows='30' cols='60'></textarea> </p> <script>//使用eventsource发送信息var eventSource = new EventSource(’/msg_send/connect’);eventSource.onmessage=function(e){ var tx=document.getElementsByTagName(’textarea’)[0]; tx.value=e.data;}; </script></body> </html>
问题解答
回答1:问题已解决,需要给发送的数据加上'data:'前缀,'nn'后缀,即'data'+msg+'nn'服务端代码修改如下:
const express = require(’express’);const router = express.Router();router.get(’/connect’,function(req,resp,next){ resp.writeHead(200,{'Content-Type':'text/event-stream','Cache-Control':'no-cache','Connection':'keep-alive' }); setInterval(function(){ resp.write('data:'+Date.now()+'nn'); },1000);});router.get(’/html’,(req,resp,next)=>{ resp.render(’./eventsource/msgsend_recevie.html’);});module.exports=router;回答2:问题
在express的response已经send后,response不允许再进行header等一系列的操作,setintval是一个定时器,你的逻辑方式没有正确。你的setintval第一次已经把响应推送出去了,那么后面这个响应已经不能继续操作了,由于http是单向非双向的,所以第二次是无效的操作
解决方案如果你希望客户端能够接受服务端得事件推送的话,我推荐使用socketio,或者使用ajax轮训去处理。
相关文章:
1. mysql 一个sql 返回多个总数2. mysql存储过程变量值为NULL3. mysql - 如何用数据库中某时间字段的 ’时分秒’ 减去 早上九点(09:00:00) 得到分钟数4. 请教使用PDO连接MSSQL数据库插入是乱码问题?5. javascript - onclick事件点击不起作用6. navicat - 数据库建索引选择的是hash,但保存后自动变成了btree|实践时mysql四种引擎都有什么要注意的?7. mysql - phpmyadmin怎么分段导出数据啊?8. html5 - 有什么好的方法防止微信公众号发红包被刷么?9. mysql - sql 中 group 和field 查询问题。10. centos环境,mysql可以用非root(普通用户)安装么?
