Chrome中Server Sent Events无法正常工作问题求助
Let's walk through the most common issues that could be breaking your SSE setup, starting with the most obvious fixes:
1. Mismatched Event Names (Critical!)
Looking at your code, your backend is sending events with the name responseBody:
eventOutput.write(new OutboundEvent.Builder() .id(decodedToken) .name("responseBody") // Event name defined here .data(String.class, respBody.toString()).build());
But your frontend is listening for an event named eventName:
source.addEventListener('eventName', (event) => { console.log(event); });
These need to match exactly! Update your frontend listener to use responseBody instead:
var evtSource = new EventSource("url"); evtSource.addEventListener('responseBody', (event) => { console.log('Received SSE data:', event.data); });
2. Ensure Jersey is Properly Configured for SSE
Double-check your Jersey setup to make sure SSE is enabled correctly:
- Confirm you have the
jersey-media-ssedependency added to your build file (Maven example below):<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-sse</artifactId> <version>your-jersey-version</version> </dependency> - Your SSE endpoint should explicitly declare it produces server-sent events:
@GET @Path("/your-sse-endpoint") @Produces(SseFeature.SERVER_SENT_EVENTS) public EventOutput getServerSentEvents() { EventOutput eventOutput = new EventOutput(); // Your event writing logic here return eventOutput; }
3. Fix Chrome's Aggressive SSE Caching
Chrome often caches SSE connections, which can make it look like events aren't coming through. Add cache-control headers to your backend response to prevent this:
// Add this when configuring your endpoint's response ResponseBuilder responseBuilder = Response.ok(eventOutput); responseBuilder.header("Cache-Control", "no-cache, no-store, must-revalidate"); responseBuilder.header("Pragma", "no-cache"); responseBuilder.header("Expires", "0"); return responseBuilder.build();
4. Resolve Cross-Origin (CORS) Issues
If your Angular app and Jersey backend are on different domains/ports, Chrome will block the SSE connection unless CORS is properly configured. Add a CORS filter to your Jersey app:
@Provider public class CORSFilter implements ContainerResponseFilter { @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { // Replace with your Angular app's URL responseContext.getHeaders().add("Access-Control-Allow-Origin", "http://your-angular-url:port"); responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, OPTIONS"); responseContext.getHeaders().add("Access-Control-Allow-Headers", "Content-Type"); responseContext.getHeaders().add("Access-Control-Allow-Credentials", "true"); } }
Don't forget to register this filter in your Jersey application configuration.
5. Add Frontend Debugging Listeners
Add error and open listeners to your EventSource to catch connection issues in Chrome DevTools:
var evtSource = new EventSource("url"); evtSource.addEventListener('responseBody', (event) => { console.log('Received SSE:', event.data); }); evtSource.addEventListener('open', () => { console.log('SSE connection opened successfully'); }); evtSource.addEventListener('error', (error) => { console.error('SSE error occurred:', error); if (error.readyState === EventSource.CLOSED) { console.log('SSE connection closed unexpectedly'); } });
Check the Network tab in DevTools to verify the SSE request is being sent, what the response status is, and if required headers are present.
6. Validate Event Format
While Jersey's OutboundEvent should handle correct formatting automatically, ensure each event follows the standard SSE structure:
id: [your-decoded-token] event: responseBody data: [your-response-body-content]
Note the blank line at the end of each event—this is required for Chrome to recognize it as a complete event.
内容的提问来源于stack exchange,提问作者Vikhyath Maiya

