在服务器关闭连接之前,浏览器不会响应服务器发送的事件
Browsers are not responding to Server-Sent Events until server closes connection
在Express/Node服务器上,我将内容类型设置为text/event-stream
:
res.writeHead(200, {
'Content-Type': 'text/event-stream'
});
然后,随着一系列回调的启动,我将数据消息写入流,并在流后面添加两行:
res.write('data: ' + JSON.stringify(data) + ''n'n');
如果我在服务器端添加日志记录,或者如果我只是用curl
点击URL,我可以看到数据消息在几秒钟内被写入。
然而,当我尝试在网页中使用这些数据消息时,什么也没发生。(我正在Mac上测试Chrome、Firefox和Safari。)以下是网页的样子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Testing</title>
</head>
<body>
<h1>Server-Sent Events Test</h1>
<script>
var source = new EventSource('/library/search?q=medicine&async');
source.onmessage = function(e) {
document.body.innerHTML += JSON.parse(e.data).name + '<br>';
};
</script>
</body>
</html>
如果我在服务器端添加最后一个回调来关闭连接(使用res.end()
),那么浏览器会同时响应所有数据消息,并且只响应res.end()
一次。这似乎违背了使用服务器发送事件的目的。
我需要更改什么(除了放弃并切换到XHR轮询)才能让浏览器在服务器发送事件到达时对其做出响应(这似乎正是服务器发送事件的用途和用例)?
(演示问题的测试页面可用,但现在这个问题已经解决,我已经将其删除。)
看起来您有一些正在进行压缩的中间件;在这样做的过程中,它是缓冲的,直到您完成响应。你可以通过卷曲看到这一点:
首先,裸GET:
curl <url>
接下来,添加一个Accept-Encoding
标头(类似于您的浏览器正在使用的标头):
curl <url> -H 'Accept-Encoding: gzip,deflate,sdch' --compressed
请注意,--compressed
只是告诉curl
为您解压缩它。
您会注意到,您在第一个上看到了预期的行为,但在第二个上看不到。这表明它与压缩有关。我建议关闭该路由的压缩,或者找到一个知道如何压缩每一帧的智能中间件。
它在Chrome中运行良好。这是我的测试代码:
sse.js:
var app = require('express')();
app.get('/', function(req, res) {
res.sendFile(__dirname + '/sse.htm');
});
app.get('/events', function(req, res) {
var counter = 0;
res.writeHead(200, { 'Content-Type': 'text/event-stream' });
setInterval(function() {
res.write('data: ' + JSON.stringify({name: 'foo' + (counter++) }) + ''n'n');
}, 1000);
res.write('data: ' + JSON.stringify({name: 'foo' + (counter++) }) + ''n'n');
});
app.listen(8000);
sse.htm:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1>Server-Sent Events Test</h1>
<script>
var source = new EventSource('/events');
source.onmessage = function(e) {
document.body.innerHTML += JSON.parse(e.data).name + '<br />';
};
source.onerror = function(e) {
source.close();
};
</script>
</body>
</html>
这会产生以下输出:
foo0//一秒钟后foo1//两秒钟后foo2//三秒后foo3//等等。
相关文章:
- 带Jquery的wep API,加载资源失败:服务器响应状态为404(未找到)
- 如何在 http 上调用 end().服务器响应对象
- 将服务器响应格式化为人类可读
- 尝试获取服务器响应
- 如何在 Javascript 函数中拦截 Web 服务器响应
- 如何从服务器响应中显示phonegap中的图像
- Nodejs-websocket:如何在没有服务器响应的情况下连续发送客户端消息
- 正在分析Meteor中的错误服务器响应
- 正在从LWIP服务器响应中检索16位整数
- 可以´t从对象XMLHttpRequest获取服务器响应
- 试图理解返回javascript方法的服务器响应
- AJAX 中的常见服务器响应页原因
- 节点服务器响应错误: process.nextTick(function(){throw err;});.
- GO 中的长时间轮询,服务器响应不当
- 在 Iframe 中发布服务器响应
- Jquery 响应从服务器响应中修剪值
- 在铁表单提交后检查服务器响应
- 量角器单击链接并将服务器响应与文件进行比较
- 如何确定 Node .js服务器响应是否已停止
- 当服务器响应缓慢时,jQuery 在加载/就绪时不触发