Difference between EventSource and XMLHttpRequest for SSE

拜拜、爱过 提交于 2021-01-28 08:03:39

问题


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

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 ...)

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

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

Here are my implementations

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.

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...


回答1:


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.

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

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.

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.

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

Pseudo code

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);


来源:https://stackoverflow.com/questions/57289483/difference-between-eventsource-and-xmlhttprequest-for-sse

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!