I'm struggling in updating the stream response from Flask on a website. Firstly, I referred to the answers from this page: Display data streamed from a Flask view as it updates and I wanted to try the demo on this page. Flask:
from flask import Response, Flask, render_template
import time
app = Flask(__name__)
@app.route('/')
def main():
return render_template('index2.html')
def generate_text_stream():
for i in range(10):
time.sleep(1)
print(f"Line {i}\n")
yield f"Line {i}\n"
@app.route('/stream')
def text_stream():
return Response(generate_text_stream(), mimetype='text/plain')
app.run(debug=False)
HTML
<p>This is the latest output: <span id="latest"></span></p>
<p>This is all the output:</p>
<ul id="output"></ul>
<script>
var latest = document.getElementById('latest');
var output = document.getElementById('output');
var xhr = new XMLHttpRequest();
xhr.open('GET', '/stream');
xhr.send();
var position = 0;
function handleNewData() {
// the response text include the entire response so far
// split the messages, then take the messages that haven't been handled yet
// position tracks how many messages have been handled
// messages end with a newline, so split will always show one extra empty message at the end
console.log(new Date());
var messages = xhr.responseText.split('\n');
console.log(messages);
messages.slice(position, -1).forEach(function(value) {
latest.textContent = value; // update the latest value in place
// build and append a new item to a list to log all output
var item = document.createElement('li');
item.textContent = value;
output.appendChild(item);
});
position = messages.length - 1;
}
var timer;
timer = setInterval(function() {
// check the response for new data
handleNewData();
// stop checking once the response has ended
if (xhr.readyState == XMLHttpRequest.DONE) {
clearInterval(timer);
latest.textContent = 'Done';
}
}, 1000);
</script>
When I run this demo, I got unexpected behavior. The 'Line X' text print in python console in every second as expected:
However, the handleNewData() function (javascript) got nothing from the server and finally got all text in the last iteration:
I expected the 'Line X' text would be sent to the website every second. Why this behavior arise and how to fix it. A lot of thanks for any help.