Support: eventsource Chrome for Android 67+ Chrome 6+ iOS Safari 4.0+ UC Browser for Android 11.8+ Firefox 6+ IE None Opera Mini None Safari 5+ Edge None Samsung Internet 4+ Opera 11+ Android Browser 4.4+
Source: caniuse.com
This section is non-normative.
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
interface
[Constructor(USVString url, optional EventSourceInit eventSourceInitDict), Exposed=(Window,Worker)]
interface EventSource : EventTarget {
readonly attribute USVString url;
readonly attribute boolean withCredentials;
// ready state
const unsigned short CONNECTING = 0;
const unsigned short OPEN = 1;
const unsigned short CLOSED = 2;
readonly attribute unsigned short readyState;
// networking
attribute EventHandler onopen;
attribute EventHandler onmessage;
attribute EventHandler onerror;
void close();
};
dictionary EventSourceInit {
boolean withCredentials = false;
};
Each
EventSource
object
has
the
following
associated
with
it:
A url (a URL record ). Set during construction.
A request . This must initially be null.
A reconnection time , in milliseconds. This must initially be a user-agent-defined value, probably in the region of a few seconds.
A last event ID string . This must initially be the empty string.
Apart
from
url
these
are
not
currently
exposed
on
the
EventSource
object.
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
".
close
()
Aborts
any
instances
of
the
fetch
algorithm
started
for
this
EventSource
object,
and
sets
the
readyState
attribute
to
CLOSED
.
url
Returns the URL providing the event stream .
withCredentials
Returns
true
if
the
credentials
mode
for
connection
requests
to
the
URL
providing
the
event
stream
is
set
to
"
include
",
and
false
otherwise.
readyState
Returns
the
state
of
this
EventSource
object's
connection.
It
can
have
the
values
described
below.
The
EventSource(
url
,
eventSourceInitDict
)
constructor,
when
invoked,
must
run
these
steps:
Let
ev
be
a
new
EventSource
object.
Let settings be ev 's relevant settings object .
Let urlRecord be the result of parsing url with settings 's API base URL and settings 's API URL character encoding .
If
urlRecord
is
failure,
then
throw
a
"
SyntaxError
"
DOMException
.
Set ev 's url to urlRecord .
Let corsAttributeState be Anonymous .
If
the
value
of
eventSourceInitDict
's
withCredentials
member
is
true,
then
set
corsAttributeState
to
Use
Credentials
and
set
ev
's
withCredentials
attribute
to
true.
Let request be the result of creating a potential-CORS request given urlRecord , the empty string, and corsAttributeState , and with the same-origin fallback flag set.
Set request 's client to settings .
User
agents
may
set
`
Accept
`/`
text/event-stream
`
in
request
's
header
list
.
Set
request
's
cache
mode
to
"
no-store
".
Set ev 's request to request .
Run this step in parallel :
Fetch request .
Return ev .
The
url
attribute's
getter
must
return
the
serialization
of
this
EventSource
object's
url
.
The
withCredentials
attribute
must
return
the
value
to
which
it
was
last
initialized.
When
the
object
is
created,
it
must
be
initialized
to
false.
The
readyState
attribute
represents
the
state
of
the
connection.
It
can
have
the
following
values:
CONNECTING
(numeric
value
0)
OPEN
(numeric
value
1)
CLOSED
(numeric
value
2)
close()
method
was
invoked.
When
the
object
is
created
its
readyState
must
be
set
to
CONNECTING
(0).
The
rules
given
below
for
handling
the
connection
define
when
the
value
changes.
The
close()
method
must
abort
any
instances
of
the
fetch
algorithm
started
for
this
EventSource
object,
and
must
set
the
readyState
attribute
to
CLOSED
.
The
following
are
the
event
handlers
(and
their
corresponding
event
handler
event
types
)
that
must
be
supported,
as
event
handler
IDL
attributes
,
by
all
objects
implementing
the
EventSource
interface:
Event handler | Event handler event type |
---|---|
onopen
|
open
|
onmessage
|
message
|
onerror
|
error
|
The
resource
indicated
in
the
argument
to
the
EventSource
constructor
is
fetched
when
the
constructor
is
run.
As data is received, the tasks queued by the networking task source to handle the data must act as follows.
HTTP
200
OK
responses
with
a
`
Content-Type
`
header
specifying
the
type
`
text/event-stream
`,
ignoring
any
MIME
type
parameters,
must
be
processed
line
by
line
as
described
below
.
When a successful response with a supported MIME type is received, such that the user agent begins parsing the contents of the stream, the user agent must announce the connection .
The
task
that
the
networking
task
source
places
on
the
task
queue
once
fetching
for
such
a
resource
(with
the
correct
MIME
type
)
has
completed
must
cause
the
user
agent
to
reestablish
the
connection
in
parallel
.
This
applies
whether
the
connection
is
closed
gracefully
or
unexpectedly
(but
does
not
apply
when
fetching
is
canceled
by
the
user
agent,
e.g.,
in
response
to
window.stop()
,
since
in
those
cases
the
final
task
is
actually
discarded).
It
doesn't
apply
for
the
error
conditions
listed
below
except
where
explicitly
specified.
HTTP 200 OK responses that have a Content-Type specifying an unsupported type, or that have no Content-Type at all, must cause the user agent to fail the connection .
Network errors that prevents the connection from being established in the first place (e.g. DNS errors), should cause the user agent to reestablish the connection in parallel , unless the user agent knows that to be futile, in which case the user agent may fail the connection .
Any
other
HTTP
response
code
not
listed
here,
as
well
as
the
cancelation
of
the
fetch
algorithm
by
the
user
agent
(e.g.
in
response
to
window.stop()
or
the
user
canceling
the
network
connection
manually)
must
cause
the
user
agent
to
fail
the
connection
.
When
a
user
agent
is
to
announce
the
connection
,
the
user
agent
must
queue
a
task
which,
if
the
readyState
attribute
is
set
to
a
value
other
than
CLOSED
,
sets
the
readyState
attribute
to
OPEN
and
fires
an
event
named
open
at
the
EventSource
object.
When a user agent is to reestablish the connection , the user agent must run the following steps. These steps are run in parallel , not as part of a task . (The tasks that it queues, of course, are run like normal tasks and not themselves in parallel .)
Queue a task to run the following steps:
If
the
readyState
attribute
is
set
to
CLOSED
,
abort
the
task.
Set
the
readyState
attribute
to
CONNECTING
.
Fire
an
event
named
error
at
the
EventSource
object.
Wait a delay equal to the reconnection time of the event source.
Optionally, wait some more. In particular, if the previous attempt failed, then user agents might introduce an exponential backoff delay to avoid overloading a potentially already overloaded server. Alternatively, if the operating system has reported that there is no network connectivity, user agents might wait for the operating system to announce that the network connection has returned before retrying.
Wait until the aforementioned task has run, if it has not yet run.
Queue a task to run the following steps:
If
the
EventSource
object's
readyState
attribute
is
not
set
to
CONNECTING
,
return.
Let
request
be
the
EventSource
object's
request
.
If
the
EventSource
object's
last
event
ID
string
is
not
the
empty
string,
set
`
Last-Event-ID
`/
last
event
ID
string
,
encoded
as
UTF-8
,
in
request
's
header
list
.
Fetch request and process the response obtained in this fashion, if any, as described earlier in this section.
When
a
user
agent
is
to
fail
the
connection
,
the
user
agent
must
queue
a
task
which,
if
the
readyState
attribute
is
set
to
a
value
other
than
CLOSED
,
sets
the
readyState
attribute
to
CLOSED
and
fires
an
event
named
error
at
the
EventSource
object.
Once
the
user
agent
has
failed
the
connection
,
it
does
not
attempt
to
reconnect!
The
task
source
for
any
tasks
that
are
queued
by
EventSource
objects
is
the
remote
event
task
source
.
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.
Since connections established to remote servers for such resources are expected to be long-lived, UAs should ensure that appropriate buffering is used. In particular, while line buffering with lines are defined to end with a single U+000A LINE FEED (LF) character is safe, block buffering or line buffering with different expected line endings can cause delays in event dispatch.
Streams must be decoded using the UTF-8 decode algorithm.
The UTF-8 decode algorithm strips one leading UTF-8 Byte Order Mark (BOM), if any.
The stream must then be parsed by reading everything line by line, with a U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF) character pair, a single U+000A LINE FEED (LF) character not preceded by a U+000D CARRIAGE RETURN (CR) character, and a single U+000D CARRIAGE RETURN (CR) character not followed by a U+000A LINE FEED (LF) character being the ways in which a line can end.
When a stream is parsed, a data buffer, an event type buffer, and a last event ID buffer must be associated with it. They must be initialized to the empty string
Lines must be processed, in the order they are received, as follows:
Dispatch the event , as defined below.
Ignore the line.
Collect the characters on the line before the first U+003A COLON character (:), and let field be that string.
Collect the characters on the line after the first U+003A COLON character (:), and let value be that string. If value starts with a U+0020 SPACE character, remove it from value .
Process the field using the steps described below, using field as the field name and value as the field value.
Process the field using the steps described below, using the whole line as the field name, and the empty string as the field value.
Once the end of the file is reached, any pending data must be discarded. (If the file ends in the middle of an event, before the final empty line, the incomplete event is not dispatched.)
The steps to process the field given a field name and a field value depend on the field name, as given in the following list. Field names must be compared literally, with no case folding performed.
Set the event type buffer to field value.
Append the field value to the data buffer, then append a single U+000A LINE FEED (LF) character to the data buffer.
If the field value does not contain U+0000 NULL, then set the last event ID buffer to the field value. Otherwise, ignore the field.
If the field value consists of only ASCII digits , then interpret the field value as an integer in base ten, and set the event stream's reconnection time to that integer. Otherwise, ignore the field.
The field is ignored.
When the user agent is required to dispatch the event , the user agent must process the data buffer, the event type buffer, and the last event ID buffer using steps appropriate for the user agent.
For Web browsers, the appropriate steps to dispatch the event are as follows:
Set the last event ID string of the event source to the value of the last event ID buffer. The buffer does not get reset, so the last event ID string of the event source remains set to this value until the next time it is set by the server.
If the data buffer is an empty string, set the data buffer and the event type buffer to the empty string and return.
If the data buffer's last character is a U+000A LINE FEED (LF) character, then remove the last character from the data buffer.
Let
event
be
the
result
of
creating
an
event
using
MessageEvent
,
in
the
relevant
Realm
of
the
EventSource
object.
Initialize
event
's
type
attribute
to
message
,
its
data
attribute
to
data
,
its
origin
attribute
to
the
serialization
of
the
origin
of
the
event
stream's
final
URL
(i.e.,
the
URL
after
redirects),
and
its
lastEventId
attribute
to
the
last
event
ID
string
of
the
event
source.
If the event type buffer has a value other than the empty string, change the type of the newly created event to equal the value of the event type buffer.
Set the data buffer and the event type buffer to the empty string.
Queue
a
task
which,
if
the
readyState
attribute
is
set
to
a
value
other
than
CLOSED
,
dispatches
the
newly
created
event
at
the
EventSource
object.
If
an
event
doesn't
have
an
"id"
field,
but
an
earlier
event
did
set
the
event
source's
last
event
ID
string
,
then
the
event's
lastEventId
field
will
be
set
to
the
value
of
whatever
the
last
seen
"id"
field
was.
For other user agents, the appropriate steps to dispatch the event are implementation dependent, but at a minimum they must set the data and event type buffers to the empty string before returning.
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
.
User agents running in controlled environments, e.g. browsers on mobile handsets tied to specific carriers, may offload the management of the connection to a proxy on the network. In such a situation, the user agent for the purposes of conformance is considered to include both the handset software and the network proxy.
For example, a browser on a mobile device, after having established a connection, might detect that it is on a supporting network and request that a proxy server on the network take over the management of the connection. The timeline for such a situation might be as follows:
EventSource
constructor.
EventSource
constructor
(possibly
including
a
`
Last-Event-ID
`
HTTP
header,
etc).
This can reduce the total data usage, and can therefore result in considerable power savings.
As
well
as
implementing
the
existing
API
and
text/event-stream
wire
format
as
defined
by
this
specification
and
in
more
distributed
ways
as
described
above,
formats
of
event
framing
defined
by
other
applicable
specifications
may
be
supported.
This
specification
does
not
define
how
they
are
to
be
parsed
or
processed.
While
an
EventSource
object's
readyState
is
CONNECTING
,
and
the
object
has
one
or
more
event
listeners
registered
for
open
,
message
or
error
events,
there
must
be
a
strong
reference
from
the
Window
or
WorkerGlobalScope
object
that
the
EventSource
object's
constructor
was
invoked
from
to
the
EventSource
object
itself.
While
an
EventSource
object's
readyState
is
OPEN
,
and
the
object
has
one
or
more
event
listeners
registered
for
message
or
error
events,
there
must
be
a
strong
reference
from
the
Window
or
WorkerGlobalScope
object
that
the
EventSource
object's
constructor
was
invoked
from
to
the
EventSource
object
itself.
While
there
is
a
task
queued
by
an
EventSource
object
on
the
remote
event
task
source
,
there
must
be
a
strong
reference
from
the
Window
or
WorkerGlobalScope
object
that
the
EventSource
object's
constructor
was
invoked
from
to
that
EventSource
object.
If
a
user
agent
is
to
forcibly
close
an
EventSource
object
(this
happens
when
a
Document
object
goes
away
permanently),
the
user
agent
must
abort
any
instances
of
the
fetch
algorithm
started
for
this
EventSource
object,
and
must
set
the
readyState
attribute
to
CLOSED
.
If
an
EventSource
object
is
garbage
collected
while
its
connection
is
still
open,
the
user
agent
must
abort
any
instance
of
the
fetch
algorithm
opened
by
this
EventSource
.
This section is non-normative.
User
agents
are
strongly
urged
to
provide
detailed
diagnostic
information
about
EventSource
objects
and
their
related
network
connections
in
their
development
consoles,
to
aid
authors
in
debugging
code
using
this
API.
For
example,
a
user
agent
could
have
a
panel
displaying
all
the
EventSource
objects
a
page
has
created,
each
listing
the
constructor's
arguments,
whether
there
was
a
network
error,
what
the
CORS
status
of
the
connection
is
and
what
headers
were
sent
by
the
client
and
received
from
the
server
to
lead
to
that
status,
the
messages
that
were
received
and
how
they
were
parsed,
and
so
forth.
Implementations
are
especially
encouraged
to
report
detailed
information
to
their
development
consoles
whenever
an
error
event
is
fired,
since
little
to
no
information
can
be
made
available
in
the
events
themselves.