您的位置:首页技术文章
文章详情页

html5 - EventSource报错

【字号: 日期:2023-09-08 10:09:00浏览:46作者:猪猪

问题描述

错误

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轮训去处理。

标签: Html5
相关文章: