I am implementing some server-side events with EventSource
and I need to know when the EventSource
connection is established and server responded with initial 200 OK
, then I can start performing some other requests which eventually result in messages sent through the EventSource from server.
I actually use this polyfill https://github.com/AlexGalays/EventSource which internally uses XMLHttpRequest.
The problem: When the server sends 200 OK + headers, onreadystatechange
is not fired (xhr.readyState
is still 1
). This is a general issue related to any XHR, not only EventSource.
Example PHP server:
<?php
sleep(5); // our actual implementation does some non-trivial startup here
// send 200 OK + headers, but no data
flush();
sleep(5);
echo "bye";
Example - client:
<script>
xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => console.log(`readystate = ${xhr.readyState}`);
xhr.open('GET', 'http://localhost/longpoll.php');
xhr.send();
</script>
Expected behavior:
- readystate = 1 (opened)
- 5 seconds delay
- readystate = 2 (headers received)
- 5 seconds delay
- readystate = 3 (loading)
- readystate = 4 (done)
Actual behavior:
- readystate = 1 (opened)
- 10 seconds delay
- readystate = 2 (headers received)
- readystate = 3 (loading)
- readystate = 4 (done)
Tested in latest Chrome (77) and Firefox (69), both behave the same.
When I observe the connection in Chrome Dev tools Network tab, I actually do see response headers and status code after the first 5 seconds delay (see https://youtu.be/sIgQnbfwxjM). This means that browser really receives headers and updates connection state after first 5 seconds, but JavaScript is not acknowledged.
Can this be somehow worked around? Or is it some security restriction that prevents me from getting updated connection status in this phase?