Edition for Web Developers — Last Updated 12 May 2025
Support in all current engines.
サーバーがHTTP経由で、または専用のサーバープッシュプロトコルを使用してウェブページにデータをプッシュできるようにするために、この仕様はEventSource
インターフェイスを導入する。
このAPIの使用は、EventSource
オブジェクトの作成とイベントリスナーの登録で構成される。
var source = new EventSource( 'updates.cgi' );
source. onmessage = function ( event) {
alert( event. data);
};
サーバー側では、スクリプト(この場合は"updates.cgi
")は、text/event-stream
のMIMEタイプで、次の形式でメッセージを送信する:
data: This is the first message. data: This is the second message, it data: has two lines. data: This is the third message.
著者は、さまざまなイベントタイプを使用してイベントを分離できる。これは、"add"および"remove"の2つのイベントタイプを持つストリームである:
event: add data: 73857293 event: remove data: 2153 event: add data: 113411
そのようなストリームを処理するためのスクリプトは次のようになる(ここでaddHandler
およびremoveHandler
は、イベントという1つの引数を取る関数である):
var source = new EventSource( 'updates.cgi' );
source. addEventListener( 'add' , addHandler, false );
source. addEventListener( 'remove' , removeHandler, false );
デフォルトのイベントタイプは "message"である。
イベントストリームは常にUTF-8としてデコードされる。別の文字エンコーディングを指定する方法は存在しない。
イベントストリームリクエストは、通常のHTTPリクエストと同様に、HTTP 301および307リダイレクトを使用してリダイレクトできる。接続が閉じられる場合にクライアントは再接続する。クライアントは、HTTP 204 No Contentレスポンスコードを使用して再接続を停止するように指示できる。
XMLHttpRequest
またはiframe
を使用してエミュレートするよりもむしろこのAPIを使用することは、ユーザーエージェントの実装者およびネットワークオペレーターが事前に調整できる場合に、ユーザーエージェントがネットワークリソースをより有効に活用可能になる。他の利点の中でも、これは、ポータブルデバイスのバッテリー寿命を大幅に節約するという結果をもたらす。これについては、下記のコネクションレスプッシュに関するセクションで詳しく説明される。
EventSource
インターフェイスSupport in all current engines.
source = new EventSource( url [, { withCredentials: true } ])
新しいEventSource
オブジェクトを作成する。
urlは、イベントストリームを提供するURLを示す文字列である。
withCredentials
をtrueに設定すると、urlへの接続リクエストの資格情報モードが"include
"に設定される。
source.close()
このEventSource
オブジェクトに対して開始されたフェッチアルゴリズムのインスタンスをすべて中止し、readyState
属性をCLOSED
に設定する。
source.url
イベントストリームを提供するURLを返す。
source.withCredentials
イベントストリームを提供するURLへの接続リクエストのクレデンシャルモードが"include
"に設定される場合はtrueを返し、そうでなければfalseを返す。
source.readyState
このEventSource
オブジェクトの接続の状態を返す。以下に説明する値を持つことができる。
CONNECTING
(数値0)OPEN
(数値1)CLOSED
(数値2)close()
メソッドが呼び出されたかのいずれか。以下は、EventSource
インターフェイスを実装するすべてのオブジェクトによって、イベントハンドラーIDL属性として、サポートされるイベントハンドラー(および対応するイベントハンドラーイベント型)である:
イベントハンドラー | イベントハンドラーイベント型 |
---|---|
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
`ヘッダーLast-Event-ID
` HTTPリクエスト ヘッダーは、ユーザーエージェントが接続を再確立するときに、EventSource
オブジェクトの最後のイベントID文字列をサーバーに報告する。
値空間をより適切に定義するには、whatwg/html issue #7363を参照。これは基本的には、U+0000 NULL、U+000A LF、またはU+000D CRを含まない、UTF-8でエンコードされた文字列である。
このイベントストリームのフォーマットのMIMEタイプは、text/event-stream
である。
イベントストリームのフォーマットは、次のABNFのstream
生成で説明されているとおりである。文字セットは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)
このフォーマットのイベントストリームは、常にUTF-8としてエンコードしなければならない。[ENCODING]
行は、U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF)文字ペア、単一のU+000A LINE FEED (LF)文字、または単一のU+000D CARRIAGE RETURN (CR)文字のいずれかで区切らなければならない。
次のイベントストリームの後には、空白行が1行続く:
data: YHOO data: +2 data: 10
インターフェイスMessageEvent
をもつイベントmessage
がEventSource
オブジェクトに送出される。イベントのdata
属性には、文字列"YHOO\n+2\n10
"が含まれる("\n
"は改行を表す)。
これは、次のように使用できる:
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 ]);
};
ここで、updateStocks()
は次のように定義された関数である:
function updateStocks( symbol, delta, value) { ... }
…など。
次のストリームには、4つのブロックが含まれている。最初のブロックにはコメントのみが含まれており、何も発火しない。2番目のブロックには、それぞれ"data"および"id"という名前の2つのフィールドがある。このブロックに対して、データ"first event"でイベントが発生し、最後のイベントIDを"1"に設定する。これにより、このブロックと次のブロックとの間の接続が切断された場合、サーバーには値`1
`の`Last-Event-ID
`ヘッダーが送信される。3番目のブロックは"second event"というデータでイベントを発火し、"id" フィールドも持っているが、今回は値が存在しない。これは、最後のイベントIDを空の文字列にリセットする(つまり、再接続が試行された場合に`Last-Event-ID
`ヘッダーが送信されなくなる)。最後に、最終ブロックは、データ" third event"(先頭に1つのスペース文字)をもつイベントを発火するだけである。最後の行は空白行で終了する必要があることに注意する。ストリームの終わりは、最後のイベントの早出をトリガーするのに十分ではない。
: test stream data: first event id: 1 data:second event id data: third event
次のストリームは、2つのイベントを発火させる:
data data data data:
最初のブロックは、データが空の文字列に設定された状態でイベントを発火させる。最後のブロックの後に空白行が続く場合も同様である。中間のブロックは、データが単一の改行文字に設定されたイベントを発火させる。最後のブロックは、その後に空白行がないため破棄される。
次のストリームは、2つの同じイベントを発火させる:
data:test data: test
これは、コロンの後のスペースが存在する場合、無視されるためである。
レガシープロキシサーバーは、特定のケースにおいて、短いタイムアウトの後にHTTP接続を切断することが知られている。そのようなプロキシサーバーから保護するために、著者は約15秒ごとにコメント行(':'文字で始まる行)を含めることができる。
イベントソース接続を相互に、または以前に配信された特定の文書に関連付けたい著者は、IPアドレスに依存することが機能しないことに気づくかもしれない。これは、個々のクライアントが複数のIPアドレスを持つことができ(複数のプロキシサーバーがあるため)、そして個々のIPアドレスが複数のクライアントを持つことができる(プロキシサーバーを共有しているため)あるためである。文書が提供されるときにその文書に一意の識別子を含め、接続が確立されるときにその識別子をURLの一部として渡す方がよい。
著者はまた、特にタイミング要件を認識しない別のレイヤーでチャンクが行われる場合、HTTPチャンクがこのプロトコルの信頼性に予期しない悪影響を与える可能性があることに注意する。これが問題である場合、イベントストリームの配信時にチャンクを無効にすることができる。
HTTPのサーバーごとの接続制限をサポートするクライアントは、各ページが同じドメインへのEventSource
を持つ場合、あるサイトから複数のページを開くときに問題が発生する可能性がある。著者は、接続ごとに一意なドメイン名を使用するという比較的複雑なメカニズムを使用する、ユーザーがページごとにEventSource
機能を有効もしくは無効にできるようにすること、または共有ワーカーを使用して単一のEventSource
オブジェクトを共有することによって、この問題を回避できる。