当前位置: 首页 > 面试题库 >

JavaScript EventSource SSE无法在浏览器中触发

荆树
2023-03-14
问题内容

我一直在开发一个nodejs服务器,以便为我正在使用HTML5开发的新网站提供服务器端事件。

当我通过telnet到服务器时,它可以正常工作,向我发送所需的HTTP响应标头,然后再发送一系列事件,这些事件我目前每2或3秒生成一次,以证明其有效。

我尝试了最新版本的FireFox,Chrome和Opera,它们创建了EventSource对象并连接到nodejs服务器,但没有一个浏览器会生成任何事件,包括onopen,onmessage和onerror。

但是,如果我停止我的nodejs服务器,终止与浏览器的连接,它们都会突然分派所有消息,并显示所有事件。然后,所有浏览器都尝试按照规范重新连接到服务器。

我将所有内容托管在网络服务器上。本地文件中没有任何内容。

我已经阅读了可以在网上找到的所有内容,包括我购买的书籍,没有任何迹象表明存在此类问题。我缺少什么吗?

服务器实现示例

  var http = require('http');
  var requests = [];

  var server = http.Server(function(req, res) {
    var clientIP = req.socket.remoteAddress;
    var clientPort = req.socket.remotePort;

    res.on('close', function() {
      console.log("client " + clientIP + ":" + clientPort + " died");

      for(var i=requests.length -1; i>=0; i--) {
        if ((requests[i].ip == clientIP) && (requests[i].port == clientPort)) {
          requests.splice(i, 1);
        }
      }
    });

    res.writeHead(200, {
      'Content-Type': 'text/event-stream', 
      'Access-Control-Allow-Origin': '*', 
      'Cache-Control': 'no-cache', 
      'Connection': 'keep-alive'});

    requests.push({ip:clientIP, port:clientPort, res:res});

    res.write(": connected.\n\n");
  });

  server.listen(8080);

  setInterval(function test() {
    broadcast('poll', "test message");
  }, 2000);

function broadcast(rtype, msg) {
  var lines = msg.split("\n");

  for(var i=requests.length -1; i>=0; i--) {
    requests[i].res.write("event: " + rtype + "\n");
    for(var j=0; j<lines.length; j++) {
      if (lines[j]) {
        requests[i].res.write("data: " + lines[j] + "\n");
      }
    }
    requests[i].res.write("\n");
  }
}

样本HTML页面

<!DOCTYPE html>
<html>
  <head>
    <title>SSE Test</title>
    <meta charset="utf-8" />
    <script language="JavaScript">
      function init() {
        if(typeof(EventSource)!=="undefined") {
          var log = document.getElementById('log');
          if (log) {
            log.innerHTML = "EventSource() testing begins..<br>";
          }

          var svrEvents = new EventSource('/sse');

          svrEvents.onopen = function() {
            connectionOpen(true);
          }

          svrEvents.onerror = function() {
            connectionOpen(false);
          }

          svrEvents.addEventListener('poll', displayPoll, false);             // display multi choice and send back answer

          svrEvents.onmessage = function(event) {
              var log = document.getElementById('log');
              if (log) {
                log.innerHTML += 'message: ' + event.data + "<br>";
              }
            // absorb any other messages
          }
        } else {
          var log = document.getElementById('log');
          if (log) {
            log.innerHTML = "EventSource() not supported<br>";
          }
        }
      }

      function connectionOpen(status) {
          var log = document.getElementById('log');
          if (log) {
            log.innerHTML += 'connected: ' + status + "<br>";
          }
      }

      function displayPoll(event) {
        var html = event.data;
          var log = document.getElementById('log');
          if (log) {
            log.innerHTML += 'poll: ' + html + "<br>";
          }
      }
    </script>
  </head>
  <body onLoad="init()">
    <div id="log">testing...</div>
  </body>
</html>

这些示例是基本示例,但与我在书本和在线版本中看到的其他所有示例都一样。如果我终止客户端连接或终止服务器,则eventSource似乎仅在工作,但这将是轮询而不是SSE,并且我特别想使用SSE。

有趣的是,诸如html5rock的thouse之类的演示在我在线使用它们时似乎也无法按预期工作。


问题答案:

破解了!:)

感谢Tom Kersten的帮助,他帮助我进行了测试。原来代码不是问题。

请注意..如果您的客户端使用任何类型的防病毒软件拦截Web请求,则可能会在此处引起问题。在这种情况下,提供企业级防病毒和防火墙保护的Sophos
Endpoint
Security具有称为Web保护的功能。在此功能中,有一个选项可以扫描下载内容;似乎SSE连接被视为下载,因此直到关闭该连接并接收要扫描的流后才将其发布给浏览器。禁用此选项可以解决此问题。我已经提交了错误报告,但其他防病毒系统可能也是如此。

感谢您的建议,并帮助大家:)



 类似资料:
  • 好吧,我知道有很多关于这个的问题和答案,但我真的没有任何运气。我有一个多类、多包程序,它也使用一些外部库(作为jar文件)。我也将我的项目导出为jar文件,下面是我的“index.html”,它引用了必要的库和我的jar文件。所有这些文件都放在同一个目录中,我可以在我的网页上看到小程序:http://easlnx01.eas.muohio.edu/~whitetc2/Twitter挖掘2/ 我的主

  • 无壳浏览器 无壳浏览器是指没有图形用户界面的 Web 浏览器. 无壳浏览器拥有一个和受欢迎的 Web 浏览器相似的环境, 并提供了网页的自动化控制, 但要通过命令行接口或使用网络通信工具执行. 对于测试网页, 无壳浏览器是非常有用的, 因为和普通浏览器一样, 它们能渲染和理解 HTML, 包括样式元素, 如: 页面布局, 颜色, 字体选择, JavaScript 的执行和 AJAX, 但是当使用其

  • 我试图创建一个类,该类将有一个接一个地测试超文本传输协议代理的方法,直到我有一个工作的代理,我可以添加到一个selenium网络驱动程序实例中。 我有一个原始输入来验证代理是否在webdriver中工作,如果它不工作,它应该测试另一个代理并请求我确认,然后关闭驱动程序或保持打开状态。(我删除了使用测试方法的if语句,因为我得到了一个错误) 当我在终端中输入“n”时,当我被要求确认时,它会关闭浏览器

  • Localhost很好,但上传到服务器时不工作 %pdf-1.3 1 0 obj<>Endobj2 0 obj<>Endobj3 0 obj<>>/Mediabox[0.000 0.000 595.280 841.890]>>Endobj4 0 obj<>stream x 2 300 p@&b m-l l,br b 5 jr k drr f b k endstream endobj 8 0 obj

  • 问题内容: 我在“ Ajax加载程序映像”中有问题。在Firefox上运行正常,但在chrome上,ajax加载程序映像似乎没有。 我在检查任何属性产品时会在边栏上有一些属性,产品会根据它进行更改,并且在ajax完成之前会生成一个预加载器图像。我正在做的是在我首先检查任何属性时在div html中插入gif图像并使用.show()方法,并且在ajax成功之后,我将div html设置为null并将