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);
EventSource
instance opens a persistent connection to an HTTP server, which sends events intext/event-stream
format. The connection remains open until closed by callingEventSource.close()
. Once the connection is opened, incoming messages from the server are delivered to your code in the form of message events. Unlike WebSockets, server-sent events are unidirectional; that is, data messages are delivered in one direction, from the server to the client (such as a user's web browser)" (MDN) – Andreas