Issue and phenomenon
When I use server sent events to the react client: the event messages can be received when I access the backend by request url directly from the browser address bar, but can never be received by the front end application, and the EventStream in Chrome Dev-Tool is empty; However, once I stop the backend server, ALL the messages are flushed/sent to the client at one time. It seems that the messageS are buffered or pended somewhere.
The node.js/express test code:
// send events to client
router.get('/events', async (req, res) => {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
setInterval(() => {
res.write(`event: message\n`);
res.write(`data: ${new Date()}"}\n\n`);
}, 2000);
}
The client javascript:
// receive events from server-side
const sse = new EventSource('/events');
sse.onmessage = (e) => {
const anaStates = JSON.parse(e.data);
console.log('WHERE ARE THE EVENTS???????'); // this line never appears in Dev-tool console
};
sse.onopen = (e) => { console.log('event is opened', e); } // this log message shows eventSource is open
sse.onerror = (e) => { console.log('event has errors', e); }
Analysis
- I have already enabled CORS by using cors middleware at the backend;
- The proxy works fine, as the other requests to the endpoints are avalaible;
- The Cache Control option settings of the response HTTP header of server-side are exactly the same with the sample code of MDN docs and it looks right.
I didn't get an answer from others or google sse, eventSource, cors or proxy. One suggested way is to disable CORS of browser:
$ google-chrome --disable-web-security
But I don't think this is a good way as we need to put things online eventually, it didn't work for debugging as well when I tried.
Solutions
This bugged me serveral hours. I luckily found two solutions by changing code line by line:
- Use full URL to request the events (may not be decent, but it works) from client side:
const sse = new EventSource('http://localhost:8080/events'); -
Set the server-side Cache Control Header to no-transform:
'Cache-Control': 'no-cache', --> 'Cache-Control': 'no-transform',or
'Cache-Control': 'no-cache', --> 'Cache-Control': 'no-cache, no-transform',
I cannot fully understand why the no-transform directive matters here. It seems that the stream Event message is compressed in gzip format(see the respond header: Content-Encoding: gizp) and cannot be decompressed automatically when using no-cache directive(or by default), so it is buffered??; when we add no-transform directive, the message is not compressed, so ... won't be buffered??
By searching no-transform with sse, I got this:
- https://www.npmjs.com/package/ssestream-no-cache-transform
- https://github.com/facebook/create-react-app/issues/1633
Anyway, these are solutions to the issue. If anyone can give a good explanation, please leave your comment here.

Comments