首页 >后端开发 >Python教程 >如何动态更新和显示从 Flask 视图流式传输的数据?

如何动态更新和显示从 Flask 视图流式传输的数据?

DDD
DDD原创
2024-12-07 05:11:10736浏览

How to Dynamically Update and Display Data Streamed from a Flask View?

显示更新时从 Flask 视图流式传输的数据

简介

在 Flask 应用程序中,通常需要显示实时生成或更新的数据。虽然 Flask 内置了对流响应的支持,但将此数据合并到 HTML 模板中可能具有挑战性。本文探讨了如何在数据流式传输到页面时动态更新、格式化和显示数据。

在 Flask 中流式传输数据

要在 Flask 中流式传输数据,您需要可以使用生成器作为对路线的响应。每次迭代响应时,生成器都会向客户端生成一块数据。例如:

@app.route('/')
def index():
    def inner():
        for i in range(500):
            # simulate a long process to watch
            j = math.sqrt(i)
            time.sleep(1)
            # this value should be inserted into an HTML template
            yield str(i) + '<br/>\n'
    return flask.Response(inner(), mimetype='text/html')

此代码模拟一个每秒生成值的长时间运行的进程。然后这些值以 HTML 片段的形式流式传输到响应。

在 JavaScript 中处理流式数据

虽然 Flask 支持流式响应,但 HTML 模板在服务器端渲染一次并且不能动态更新。要在浏览器中处理流数据,您可以使用 JavaScript 向端点发出请求,并在流数据到达时对其进行处理。

一种方法是使用 XMLHttpRequest (XHR) 对象创建一个请求流端点。然后,您可以从响应中读取数据,直至完成。下面是一个示例:

var xhr = new XMLHttpRequest();
xhr.open('GET', '{{ url_for('stream') }}');
xhr.send();
var position = 0;

function handleNewData() {
    // the response text includes 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
    var messages = xhr.responseText.split('\n');
    messages.slice(position, -1).forEach(function(value) {
        // Update the displayed data using JavaScript
        latest.textContent = value;  // update the latest value in place
        // Append the current value to a list to log all output
        var item = document.createElement('li');
        item.textContent = value;
        output.appendChild(item);
    });
    position = messages.length - 1;
}

// Check for new data periodically
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);

此 JavaScript 代码使用 XMLHttpRequest 对象创建对流端点的请求。然后它会设置一个计时器来定期检查新数据并相应地更新页面。

使用 iframe 进行流式 HTML 输出

显示从流式传输的数据的另一种方法Flask视图就是使用iframe。 iframe 是一个单独的文档,可用于显示流式 HTML 输出。下面是一个示例:

@app.route('/stream')
def stream():
    @stream_with_context
    def generate():
        # Serve initial CSS to style the iframe
        yield render_template_string('<link rel=stylesheet href="{{ url_for("static", filename="stream.css") }}">')

        # Continuously stream HTML content within the iframe
        for i in range(500):
            yield render_template_string('<p>{{ i }}: {{ s }}</p>\n', i=i, s=sqrt(i))
            sleep(1)

    return app.response_class(generate())
<p>This is all the output:</p>
<iframe src="{{ url_for('stream') }}"></iframe>

此代码使用stream_with_context 装饰器来增强生成器以支持其他功能。它提供初始 CSS 来设置 iframe 的样式,并在 iframe 中持续流式传输 HTML 内容。 iframe 中的 HTML 模板可以更复杂,并且可以根据需要包含不同的格式。

以上是如何动态更新和显示从 Flask 视图流式传输的数据?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn