最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - EventSource.onmessage is not firing even though Flask server push seems to work - Stack Overflow

programmeradmin0浏览0评论

I created a route /stream which should push the string 'test' every second.

When I open this URL (localhost:12346/stream) on Chrome, it indeed opens a blank page and a "test" is appended to the page every second, so I think the server side is working correctly. When I opened it on Firefox, it treats it as a file download that never finishes.

But when I open client.html below, the onmessage event of the EventSource object is never fired so I get no data. The onopen event was fired and I see it in the console. Why is this? How can I receive the data in the JavaScript side?

server.py:

import flask
import flask_cors
import time

app = flask.Flask(__name__)
app.debug = True
flask_cors.CORS(app)

def event_stream():
    while True:
        time.sleep(1)
        yield 'test\n'

@app.route('/stream')
def stream():
    return flask.Response(event_stream(), mimetype='text/event-stream')

app.run(port=12346, threaded=True)

client.html:

<!DOCTYPE html>
<html>
  <body>
    <script>
        var source = new EventSource('http://localhost:12346/stream');
        source.onopen = e => console.log('opened', event);
        source.onerror = e => console.log('error', event);
        source.onmessage = e => console.log('onmessage', event);
    </script>
  </body>
</html>

I created a route /stream which should push the string 'test' every second.

When I open this URL (localhost:12346/stream) on Chrome, it indeed opens a blank page and a "test" is appended to the page every second, so I think the server side is working correctly. When I opened it on Firefox, it treats it as a file download that never finishes.

But when I open client.html below, the onmessage event of the EventSource object is never fired so I get no data. The onopen event was fired and I see it in the console. Why is this? How can I receive the data in the JavaScript side?

server.py:

import flask
import flask_cors
import time

app = flask.Flask(__name__)
app.debug = True
flask_cors.CORS(app)

def event_stream():
    while True:
        time.sleep(1)
        yield 'test\n'

@app.route('/stream')
def stream():
    return flask.Response(event_stream(), mimetype='text/event-stream')

app.run(port=12346, threaded=True)

client.html:

<!DOCTYPE html>
<html>
  <body>
    <script>
        var source = new EventSource('http://localhost:12346/stream');
        source.onopen = e => console.log('opened', event);
        source.onerror = e => console.log('error', event);
        source.onmessage = e => console.log('onmessage', event);
    </script>
  </body>
</html>
Share Improve this question edited May 10, 2019 at 13:37 Dylan 2,2193 gold badges31 silver badges52 bronze badges asked May 10, 2019 at 11:53 Vincentius KevinVincentius Kevin 3796 silver badges17 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 6

Though it was later for years.. I faced the same problem with you (message appended to the page but not fired to EventStream)

After search so much examples & test for hours I found some key

You need to yield message with data: prefix and \n suffix, like data:test\n\n

So this should work for you.

def event_stream():
    while True:
        time.sleep(1)
        yield 'data:test\n\n'

And you can see the EventStream with Type=message, Data=test in Chrome Debug Tools (as also source.onmessage)

I think it has another key word like data:, but I didn't find out the document about this, maybe someone can supplement.

Server sent event EventStream does not trigger "onmessage" but Chrome Debug shows data in "EventStream" tab

That resolved my problem, backend was sending events with custom type which not triggers onmessage callback

you can avoid this problem by add @cross_origin() in your code.

import flask
from flask_cors import cross_origin
import time

app = flask.Flask(__name__)

@app.route('/stream')
@cross_origin()
def stream():
    def event_stream():
        while True:
            yield "data:" + "test" + "\n\n"
            time.sleep(1)

    return flask.Response(event_stream(), mimetype='text/event-stream')

app.run(port=12346)

This is the html file

<html>
  <head>
  </head>
  <body>

    <script>

    var source = new EventSource('http://127.0.0.1:12346/stream');
    console.log(source)
    source.onmessage = function(event) {
        console.log(event.data);        
    }

    </script>

  </body>

</html>
发布评论

评论列表(0)

  1. 暂无评论