Edition for Web Developers — Last Updated 21 November 2024
Support in all current engines.
To enable servers to push data to web pages over HTTP or using dedicated server-push protocols,
this specification introduces the EventSource
interface.
Using this API consists of creating an EventSource
object and registering an event
listener.
var source = new EventSource( 'updates.cgi' );
source. onmessage = function ( event) {
alert( event. data);
};
On the server-side, the script ("updates.cgi
" in this case) sends
messages in the following form, with the text/event-stream
MIME type:
data: This is the first message. data: This is the second message, it data: has two lines. data: This is the third message.
Authors can separate events by using different event types. Here is a stream that has two event types, "add" and "remove":
event: add data: 73857293 event: remove data: 2153 event: add data: 113411
The script to handle such a stream would look like this (where addHandler
and removeHandler
are functions that take one argument, the event):
var source = new EventSource( 'updates.cgi' );
source. addEventListener( 'add' , addHandler, false );
source. addEventListener( 'remove' , removeHandler, false );
The default event type is "message".
Event streams are always decoded as UTF-8. There is no way to specify another character encoding.
Event stream requests can be redirected using HTTP 301 and 307 redirects as with normal HTTP requests. Clients will reconnect if the connection is closed; a client can be told to stop reconnecting using the HTTP 204 No Content response code.
Using this API rather than emulating it using XMLHttpRequest
or an
iframe
allows the user agent to make better use of network resources in cases where
the user agent implementer and the network operator are able to coordinate in advance. Amongst
other benefits, this can result in significant savings in battery life on portable devices. This
is discussed further in the section below on connectionless
push.
EventSource
interfaceSupport in all current engines.
source = new EventSource(
url [, { withCredentials:
true } ])
Creates a new EventSource
object.
url is a string giving the URL that will provide the event stream.
Setting withCredentials
to true
will set the credentials mode for
connection requests to url to "include
".
source.close()
Aborts any instances of the fetch algorithm started for
this EventSource
object, and sets the readyState
attribute to CLOSED
.
source.url
Returns the URL providing the event stream.
source.withCredentials
Returns true if the credentials mode
for connection requests to the URL providing the event
stream is set to "include
", and false otherwise.
source.readyState
Returns the state of this EventSource
object's connection. It can have the
values described below.
CONNECTING
(numeric value 0)OPEN
(numeric value 1)CLOSED
(numeric value 2)close()
method was invoked.The following are the event handlers (and their corresponding event handler event types) supported,
as event handler IDL attributes, by all objects implementing the
EventSource
interface:
Event handler | Event handler event type |
---|---|
onopen Support in all current engines. Firefox6+Safari5+Chrome6+ Opera12+Edge79+ Edge (Legacy)?Internet ExplorerNo Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+ | open
|
onmessage Support in all current engines. Firefox6+Safari5+Chrome6+ Opera12+Edge79+ Edge (Legacy)?Internet ExplorerNo Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+ | message
|
onerror Support in all current engines. Firefox6+Safari5+Chrome6+ Opera12+Edge79+ Edge (Legacy)?Internet ExplorerNo Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+ | error
|
Last-Event-ID
` headerThe Last-Event-ID
` HTTP request header reports an
EventSource
object's last event ID
string to the server when the user agent is to reestablish the connection.
See whatwg/html issue #7363 to define the value space better. It is essentially any UTF-8 encoded string, that does not contain U+0000 NULL, U+000A LF, or U+000D CR.
This event stream format's MIME type is text/event-stream
.
The event stream format is as described by the stream
production of the
following ABNF, the character set for which is Unicode. [ABNF]
stream = [ bom ] * event
event = * ( comment / field ) end-of-line
comment = colon * any-char end-of-line
field = 1* name-char [ colon [ space ] * any-char ] end-of-line
end-of-line = ( cr lf / cr / lf )
; characters
lf = %x000A ; U+000A LINE FEED (LF)
cr = %x000D ; U+000D CARRIAGE RETURN (CR)
space = %x0020 ; U+0020 SPACE
colon = %x003A ; U+003A COLON (:)
bom = %xFEFF ; U+FEFF BYTE ORDER MARK
name-char = %x0000-0009 / %x000B-000C / %x000E-0039 / %x003B-10FFFF
; a scalar value other than U+000A LINE FEED (LF), U+000D CARRIAGE RETURN (CR), or U+003A COLON (:)
any-char = %x0000-0009 / %x000B-000C / %x000E-10FFFF
; a scalar value other than U+000A LINE FEED (LF) or U+000D CARRIAGE RETURN (CR)
Event streams in this format must always be encoded as UTF-8. [ENCODING]
Lines must be separated by either a U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF) character pair, a single U+000A LINE FEED (LF) character, or a single U+000D CARRIAGE RETURN (CR) character.
The following event stream, once followed by a blank line:
data: YHOO data: +2 data: 10
...would cause an event message
with the interface
MessageEvent
to be dispatched on the EventSource
object. The event's
data
attribute would contain the string "YHOO\n+2\n10
" (where "\n
" represents a newline).
This could be used as follows:
var stocks = new EventSource( "https://stocks.example.com/ticker.php" );
stocks. onmessage = function ( event) {
var data = event. data. split( '\n' );
updateStocks( data[ 0 ], data[ 1 ], data[ 2 ]);
};
...where updateStocks()
is a function defined as:
function updateStocks( symbol, delta, value) { ... }
...or some such.
The following stream contains four blocks. The first block has just a comment, and will fire
nothing. The second block has two fields with names "data" and "id" respectively; an event will
be fired for this block, with the data "first event", and will then set the last event ID to "1"
so that if the connection died between this block and the next, the server would be sent a
`Last-Event-ID
` header with the value `1
`. The third block
fires an event with data "second event", and also has an "id" field, this time with no value,
which resets the last event ID to the empty string (meaning no `Last-Event-ID
`
header will now be sent in the event of a reconnection being attempted). Finally, the last block
just fires an event with the data " third event" (with a single leading space
character). Note that the last still has to end with a blank line, the end of the stream is not
enough to trigger the dispatch of the last event.
: test stream data: first event id: 1 data:second event id data: third event
The following stream fires two events:
data data data data:
The first block fires events with the data set to the empty string, as would the last block if it was followed by a blank line. The middle block fires an event with the data set to a single newline character. The last block is discarded because it is not followed by a blank line.
The following stream fires two identical events:
data:test data: test
This is because the space after the colon is ignored if present.
Legacy proxy servers are known to, in certain cases, drop HTTP connections after a short timeout. To protect against such proxy servers, authors can include a comment line (one starting with a ':' character) every 15 seconds or so.
Authors wishing to relate event source connections to each other or to specific documents previously served might find that relying on IP addresses doesn't work, as individual clients can have multiple IP addresses (due to having multiple proxy servers) and individual IP addresses can have multiple clients (due to sharing a proxy server). It is better to include a unique identifier in the document when it is served and then pass that identifier as part of the URL when the connection is established.
Authors are also cautioned that HTTP chunking can have unexpected negative effects on the reliability of this protocol, in particular if the chunking is done by a different layer unaware of the timing requirements. If this is a problem, chunking can be disabled for serving event streams.
Clients that support HTTP's per-server connection limitation might run into trouble when
opening multiple pages from a site if each page has an EventSource
to the same
domain. Authors can avoid this using the relatively complex mechanism of using unique domain names
per connection, or by allowing the user to enable or disable the EventSource
functionality on a per-page basis, or by sharing a single EventSource
object using a
shared worker.