html icon indicating copy to clipboard operation
html copied to clipboard

Setting headers for EventSource

Open chicoxyzzy opened this issue 8 years ago • 71 comments
trafficstars

Seems like there is no way to add Authorization header or any other headers for EventSource. Is there any reason it shouldn't be possible?

chicoxyzzy avatar Dec 14 '16 14:12 chicoxyzzy

The main reason to not allow this is that this feature can somewhat easily be written on top of fetch(). I'm not sure we need put more effort into the "legacy" XMLHttpRequest, WebSocket, and EventSource networking APIs.

annevk avatar Dec 15 '16 08:12 annevk

Hmm... I have not seen any SSE alternatives based on Fetch yet. Do you know any implementations?

chicoxyzzy avatar Dec 15 '16 14:12 chicoxyzzy

No, sorry. It's also still a little early since only Chrome supports https://streams.spec.whatwg.org/ for now. But you can build any kind of abstraction on top of that. You would also no longer be limited by the SSE format and such.

annevk avatar Dec 15 '16 16:12 annevk

How should we cancel a Fetch stream? Cancelable Promises proposal is withdrawn.

chicoxyzzy avatar Dec 15 '16 21:12 chicoxyzzy

stream.cancel()

domenic avatar Dec 15 '16 21:12 domenic

Closing this since I don't think we'll be able to find sufficient interest to extend this API.

annevk avatar Dec 16 '16 10:12 annevk

@annevk What would indicate a sufficient interest?

SSE is IMO a really nice standard for implementing simple web-based queue-consumers with out of the box at least once consumption semantic and I think it has very real use-cases. But as stated above it obviously lacks the following capabilities:

  • Provide authentication as HTTP-Header
  • Provide an initial Last-Event-ID-Header that can be used to step into an already partially consumed stream (e.g. to resume from a certain position after a page reload).

There are also quite a lot active server-side implementations of SSE out there.

It's use-cases really come to shine with event-based/ reactive backends. Something that is, compared to REST, not necessarily the thing yet, but (given all the reactive/async/streaming movement going on in the backend world) seems to be relevant enough (probably needs references).

It would of course be possible to build something similar with fetch - but it would not follow any standard and assumptions like "hey this client library and that server library supports SSE - so we can probably wire them together" will no longer hold. And beside this spec there is no such thing as standard GET for event streams.

So, I'd second to keep the EventSource/SSE standard alive and move it forward to support custom headers.

danielwegener avatar Feb 08 '17 07:02 danielwegener

I'm not sure, but over the past decade I've heard this request from three people or so, which is not really enough. Also, you can continue to use server-sent events and the server-side implementations thereof, you would just need to implement the client-side bits using fetch() if you want to transmit more headers.

annevk avatar Feb 08 '17 08:02 annevk

Make it four. :) We recently chose SSE over Web Sockets for a reactive app because it's much simpler to program against and the built-in reliability is nice. Having to work around the lack of custom headers support by putting the authorization token in the query string is probably the one thing really missing from the standard. Why should we pause use of a perfectly good technology and wait until replacements come out?

LarsKemmann avatar Apr 11 '17 22:04 LarsKemmann

I have a working implementation, forked from Yaffle's polyfill.

https://github.com/Yaffle/EventSource/compare/master...kmayer:kmayer-2

kmayer avatar Jul 10 '17 17:07 kmayer

Given the (renewed) interest in this I'll reopen. We'll still need implementer interest.

annevk avatar Jul 11 '17 10:07 annevk

Great!

mkurz avatar Jul 11 '17 10:07 mkurz

Could someone with edit permission correct EvenSource -> EventSource in the title?

I think this is easy to implement on Chromium and wouldn't introduce so much complexity. Wanna hear other vendors' interest.

tyoshino avatar Sep 26 '17 02:09 tyoshino

I work on the team that maintains EventSource for Chrome. EventSource is not being actively developed. We feel resources are better spent in filling the gaps in the more generally-useful facilities provided by fetch().

To give some idea of scale, fetch() body streaming is already used on ten times as many pages as EventSource in Chrome.

I acknowledge that the resumption facilities provided by EventSource are very convenient. However, you can already achieve the same things, with more control, in browsers that support fetch() streaming. I expect that every everfresh browser will support fetch() streaming before any browser supports setting headers for EventSource.

To be clear, I don't oppose improvements to EventSource. @danielwegener's arguments in https://github.com/whatwg/html/issues/2177#issuecomment-278254601 are very persuasive. However, my team cannot justify spending any resources on it.

In summary: possible? yes. Likely to happen? no.

ricea avatar Sep 26 '17 02:09 ricea

I'll +1 on wanting to set the Last-Event-ID header in the initial request. The query string can be used as a pretty simple workaround but it's unfortunate to not be able to use an existing mechanism for the initial request.

I was looking into using fetch to consume the event-stream but it seems like I would have to reimplement the parsing and automatic reconnects which is a lot more work than I'm willing to go for.

essen avatar Jun 22 '18 09:06 essen

So if I understand correctly what is being said here it that SSE and WS are old technologies that should no longer be supported and authorization is not important to use it from a browser, even though every other client library does support Authorization headers... And while there is no real cross browser support for fetch or any protocol that would enable developers to use like WS or SSE, the only option is to send what would normally go thru a header as a query string.

@ricea would it really take more than a 2 week sprint to add this to chrome? Honestly?!

webmutation avatar Jul 11 '18 17:07 webmutation

Exactly. I love the promise (pun intended) of fetch and streams, but doing right by the existing standards adds customer value now for a set of use cases that are becoming increasingly important while the implementers' roadmaps can continue to (slowly) converge on stream-composable fetch-based solutions.

LarsKemmann avatar Jul 11 '18 19:07 LarsKemmann

2 years later, not a single browser has full support for fetch() streaming and we still can't set headers on EventSource :man_shrugging:

julienmachon avatar Jan 31 '19 14:01 julienmachon

@julienmachon actually fetch streaming is supported in these browsers:

  • [x] Chrome 43+
  • [x] Edge 16+
  • [x] Safari 10+
  • [x] Opera 29+
  • [x] Firefox 65+.

It's still would be great to use headers in SSE though.

chicoxyzzy avatar Jan 31 '19 14:01 chicoxyzzy

@chicoxyzzy according to this https://caniuse.com/#feat=streams we only have partial support for fetch streaming but maybe it's enough for reading serve-sent event (although Firefox under a flag is a bit of a bummer)

If you have some fetch streaming examples playing nicely with SSE, I'd love to see them! :grimacing:

julienmachon avatar Jan 31 '19 14:01 julienmachon

@julienmachon all of browsers support ReadableStreams in streaming response body so it should be enough for most cases.

Unfortunately I don't have any examples with fetch streaming right now, I use WebSockets mostly.

chicoxyzzy avatar Jan 31 '19 14:01 chicoxyzzy

Hi there I'm also stumped with SSE not supporting headers after all this while, if anyone does have an example for using the fetch streaming alternative that has been suggested it'd be awesome if they drop a gist link

eokoneyo avatar Apr 01 '19 10:04 eokoneyo

For setting authorization headers yaffle polyfill seems to be pretty good. It works on IE as well https://github.com/Yaffle/EventSource I have tested in chrome, fire and IE

You could pass in header and also control the heart beats

//See to that EventSource is tagged to Polyfill version and must for chrome and firefox else it would fall back to native eventsource which does not support headers

    var EventSource = EventSourcePolyfill; 
    const versionEventSource = new EventSource('http://localhost:8080/versions',{
      headers: {
        'Authorization': 'my jwt token'
      },
      heartbeatTimeout: 300000 //5 minutes else 45 seconds by default, it initiates another request
    });

Only cons is that in chrome EventStream windows we cannot see the messages as it is not it's native EventSource. Otherwise it is all good.

GirishKumar0310 avatar Apr 02 '19 14:04 GirishKumar0310

@maziey93 @julienmachon the Yaffle/EventSource library actually uses fetch streams internally (and falls back on xhr) - so you could just think of that library as a working implementation of using fetch streams to consume server sent events. (...an implementation that also happens to conform to the EventSource spec).

https://github.com/Yaffle/EventSource/blob/master/src/eventsource.js

@ricea

EventSource is not being actively developed. We feel resources are better spent in filling the gaps in the more generally-useful facilities provided by fetch().

Are these really conflicting interests for browser vendors, when it's likely (?) that native implementations are using Fetch internally also? Or could quite easily use fetch streams - as in the polyfill above?

EventSource could perhaps accept a Request object (optionally) in place of the URL string (i.e. the same parameters as Fetch currently accepts): https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters

(could then pass custom headers etc.. via the Request object)

ejdaly avatar Apr 26 '19 20:04 ejdaly

@ejdaly thanks for clarifying about Yaffle/EventSource. I do love the idea of being able to pass a Request object, in fact it'd be a no brainer if native implementations use fetch internally.

eokoneyo avatar Apr 29 '19 16:04 eokoneyo

It would also be great if there was an officially supported polyfill or package that basically replaced the browser eventsource, implementing fetch internally. Would satisfy both parties.

If the polyfill mentioned above is great, maybe validate it and put it as a suggested polyfill to use instead of the default browser eventsource.

mmaqsood avatar May 22 '19 03:05 mmaqsood

With new Chromium-based Edge browser release we will have SSE support in all major browsers

chicoxyzzy avatar May 22 '19 03:05 chicoxyzzy

Is the recommended approach, if using browser Eventsource, to pass authentication tokens via cookies or the url? Those two seem like the only options.

You can still protect your site from csrf by having your sse events trigger no state changes - just fetches of data, or prevent your site from being loaded by a different domain.

mmaqsood avatar May 22 '19 11:05 mmaqsood

Am I the only one not understanding the reasoning behind this? I mean, I understand there‘s fetch streaming but you still need to implement reading the standardized SSE response yourself in JavaScript. It‘s slower and there are no native debugging tools contrary to EventSource. So we have a standard but should implement the browser side ourselves because of not being able to set headers? Although EventSource is 95% there, native, stable and fast? I‘m slightly confused :)

Toflar avatar Feb 15 '20 06:02 Toflar

@Toflar I really do understand your frustrations, I’ve had to abandon my use case for SSE because although the polyfill for EventSource works it feels obtrusive unlike the native implementation. This issue has been tagged needs implementer interest I think that’s what we should focus on if we want to land header support for EventSource

eokoneyo avatar Feb 15 '20 07:02 eokoneyo