SSE 的 EventSource 和 XMLHttpRequest 的区别 [英] Difference between EventSource and XMLHttpRequest for SSE

查看:62
本文介绍了SSE 的 EventSource 和 XMLHttpRequest 的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实现服务器发送事件应用程序逻辑.服务器端已经完成,我现在正在处理客户端部分.

I am implementing a Server Send Event application logic. The server side is done and I'm dealing now with the client part.

无论我在哪里,JS 都在使用 EventSource 对象,这看起来非常合乎逻辑,因为它是为它而生的!但这也有很多限制(只有 GET 请求,没有标题,没有数据......)

Everywhere I look, the JS is using an EventSource Object, which seems higly logical as it is made for it ! But which has also a lot of limitation (only GET requests, no headers, no data ...)

我在问自己:为什么不改用 XMLHttpRequest 对象?

I am asking myself : why not using an XMLHttpRequest Object instead ?

我访问的服务器是用 Java EE 编写的,并返回文本/事件流类型的响应.

The server I am accessing to is written in Java EE and returns a text/event-stream typed response.

这是我的实现

var source = new EventSource("my_url");
source.onmessage = function (event) {
  console.log(event.data);
};

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
  if (xhttp.readyState == 3) {
    console.log(xhttp.response);
  }
};
xhttp.open("GET", "my_url", true);
xhttp.send();

两者都工作正常,但由于我完全没有发现有关该主题的信息,所以如果我没有做一些糟糕的事情,我会犹豫不决.

Both works fine, but as I've found absolutely no information on the topic, I'm wordering if I'm not doing something terrible.

我能看到的唯一区别是,使用 Ajax,响应会一个接一个地连接起来.我推断服务器缓冲区没有被刷新,但我对所有这些 HTTP 层的理解非常低......

The only difference I can see is that with Ajax, the responses are concatenated the ones after the others. I've deduced that the server buffer wasn't flushed but my understanding of all those HTTP layers is really low...

推荐答案

TL;DR: EventSource 处理流事件,它可以是关于每个更新"的多条信息.Ajax 没有开箱即用地处理这个问题,实现类似的行为可能非常复杂.

TL;DR: EventSource handles streaming events, which can be multiple pieces of information on each "update". Ajax does not handle this out of the box, and it can be very complicated to implement a like behavior.

您的 XMLHttpRequest 不会是一个流,因为您只会在 XMLHttpRequest.readyState 更改.

Your XMLHttpRequest wouldn't be a stream, because you would only get data on a XMLHttpRequest.readyState change.

可以使用XMLHttpRequest 高级功能 集,其中的支持有点狡猾(尽管仍然比 EventSource 好).

You can get a content stream using the onprogress event in the XMLHttpRequest advanced features set, where support is a little dodgy (though still better than EventSource).

但是,您无法检测每个进度滴答中的新"数据,因此必须按照 这个答案.

However you don't get a way of detecting what is "new" data in each progress tick and so will have to invent your own update event handling as described in this answer.

即使有了上述答案,您仍然需要一种在一次更新中区分多个事件的方法,因此您必须执行一些操作,例如将数据作为 JSON 字符串发送、解析它们然后进行您自己的事件处理.

Even with said answer, you still need a way of differentiating multiple events in one update, so you would have to do something like sending data as JSON strings, parsing them and then do your own event handling.

以上所有内容都已通过 EventSource 处理,这就是人们使用它的原因.

All of the above is already handled with EventSource and that is why people use it.

伪代码

一个 XHR 事件流实现看起来像这样:

An XHR event stream implementation would look something like this:

JavaScript

function Stream(updateCallback) {
    //last response length
    var last_response_len = 0;
    //Create XHR object
    var xhttp = new XMLHttpRequest();
    //Add eventlistener
    xhttp.onprogress = function () {
        //Get new part of response
        var responseText = xhttp.response.substr(last_response_len);
        //Set new response position
        last_response_len = xhttp.response.length;
        //Split into individual events, using a safe seperator which won't naturally occur in your events
        responseText.split("▼")
            //Only keep non-empty events to prevent JSON.parse error
            .filter(function (l) { return l.length > 0; })
            //Loop through events
            .forEach(function (text) {
            //Parse JSON to functional objects
            var data = JSON.parse(text);
            //Do something with each data element
            for (var key in data) {
                //Ignore potential prototype keys
                if (data.hasOwnProperty(key)) {
                    //Do event handling of some sort
                    updateCallback(data[key], key);
                }
            }
        });
    };
    //Initialize request
    xhttp.open("POST", "./", true);
    //Send Request
    xhttp.send();
}
// # TEST # //
//Output elements
var header = document.body.appendChild(document.createElement("h1"));
var values = document.body.appendChild(document.createElement("h2"));
//Event handling function
function OnUpdate(value, key) {
    if (key == 'header') {
        header.innerHTML = value;
    }
    if (key == 'value') {
        values.innerHTML = value;
    }
}
//Start stream
Stream(OnUpdate);

这篇关于SSE 的 EventSource 和 XMLHttpRequest 的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆