如何在服务器端的 Flask 中完成服务器发送事件时重定向?
How to redirect when server-sent-event is finished in Flask on server side?
问题
当 server-sent-event 在 Flask 和服务器端完成时如何重定向到另一个页面?
问题描述
在客户端代码 (JavaScript) 上实现了一个 EventSource,在服务器端代码 (Flask, Python) 上返回了一个 Response。如果从服务器发送了最后一个项目,则 EventSource 将关闭。我看不到通过服务器端代码重定向到另一个站点的明确解决方案。也许答案很简单,但我不明白。
类似问题
类似的问题是How to stop Server-Sent Events and one possible answer in the comment How do server-sent events actually work?。我不确定 php 和 python 是否相同,所以我为此提出了一个新问题。我也没听懂
EDIT How do I close a Server-Send Events connection in Flask? 与这个问题密切相关。那里的问题主要是看看如何从 Flask 中停止 SSE。
客户端的工作解决方案
所以我想出了一个可行的解决方案(进度条),但仅限于客户端。我必须如何更改代码才能获得通过 Flask 函数重新连接的工作示例?
相关代码片段
HTML/Jinja
{% block additional_stylesheets %}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="{{ url_for('static', filename='data_import.css') }}" />
{% endblock %}
{% block additional_javascripts %}
<script src="{{ url_for('static', filename='js/data_import.js') }}"></script>
{% endblock %}
{% block content %}
<div class="progress">
<div class="progress-bar progress-bar-striped active"
role="progressbar" aria-valuenow="0" aria-valuemin="0"
aria-valuemax="100">
</div>
</div>
{% endblock %}
JavaScript
$(document).ready(function()
{
var source = new EventSource("/progress");
source.addEventListener('import-progress', function(event)
{
$('.progress-bar')
.css('width', event.data + '%')
.attr('aria-valuenow', event.data);
}, false
);
source.addEventListener('last-item', function()
{
source.close();
redirect();
}, false
);
}
);
# This works! But how to do the same thing without calling redirect()
# on client site?
function redirect()
{
window.document.location.href = window.location.protocol + "//" +
window.location.host + "/products.html";
}
烧瓶
from foo import app
from flask import render_template, Response
@app.route('/data_import.html')
def data_import():
return render_template(
'data_import.html')
@app.route('/progress')
def progress():
return Response(import_progress(), mimetype='text/event-stream')
def import_progress():
"""
Just a small example
"""
for number in range(1, 101):
sse_id = str(number)
sse_progress = str(number)
sse_event = 'import-progress'
if number == 100:
sse_event = 'last-item'
yield "id:{_id}\nevent:{event}\ndata:{progress}\n\n".format(
_id=sse_id, event=sse_event, progress=sse_progress)
我尝试了很多让重定向工作。但我不知道该怎么做。到目前为止的每一次尝试都失败了。
您要做的是将重定向 URL 作为最后一个事件发送 - 您仍然需要使用 JavaScript 进行重定向,但您不必对路径进行硬编码还有:
def import_progress():
"""
Just a small example
"""
for number in range(1, 101):
sse_id = str(number)
sse_data = str(number)
sse_event = 'import-progress'
if number == 100:
sse_event = 'last-item'
sse_data = url_for('product_list')
yield "id:{_id}\nevent:{event}\ndata:{data}\n\n".format(
_id=sse_id, event=sse_event, data=sse_data)
然后您的最后一项处理程序变为:
source.addEventListener('last-item', function(event) {
source.close();
redirect(event.data);
}, false
);
并且redirect
变得简单:
function redirect(url) {
document.location = url;
}
问题
当 server-sent-event 在 Flask 和服务器端完成时如何重定向到另一个页面?
问题描述
在客户端代码 (JavaScript) 上实现了一个 EventSource,在服务器端代码 (Flask, Python) 上返回了一个 Response。如果从服务器发送了最后一个项目,则 EventSource 将关闭。我看不到通过服务器端代码重定向到另一个站点的明确解决方案。也许答案很简单,但我不明白。
类似问题
类似的问题是How to stop Server-Sent Events and one possible answer in the comment How do server-sent events actually work?。我不确定 php 和 python 是否相同,所以我为此提出了一个新问题。我也没听懂
EDIT How do I close a Server-Send Events connection in Flask? 与这个问题密切相关。那里的问题主要是看看如何从 Flask 中停止 SSE。
客户端的工作解决方案
所以我想出了一个可行的解决方案(进度条),但仅限于客户端。我必须如何更改代码才能获得通过 Flask 函数重新连接的工作示例?
相关代码片段
HTML/Jinja
{% block additional_stylesheets %}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="{{ url_for('static', filename='data_import.css') }}" />
{% endblock %}
{% block additional_javascripts %}
<script src="{{ url_for('static', filename='js/data_import.js') }}"></script>
{% endblock %}
{% block content %}
<div class="progress">
<div class="progress-bar progress-bar-striped active"
role="progressbar" aria-valuenow="0" aria-valuemin="0"
aria-valuemax="100">
</div>
</div>
{% endblock %}
JavaScript
$(document).ready(function()
{
var source = new EventSource("/progress");
source.addEventListener('import-progress', function(event)
{
$('.progress-bar')
.css('width', event.data + '%')
.attr('aria-valuenow', event.data);
}, false
);
source.addEventListener('last-item', function()
{
source.close();
redirect();
}, false
);
}
);
# This works! But how to do the same thing without calling redirect()
# on client site?
function redirect()
{
window.document.location.href = window.location.protocol + "//" +
window.location.host + "/products.html";
}
烧瓶
from foo import app
from flask import render_template, Response
@app.route('/data_import.html')
def data_import():
return render_template(
'data_import.html')
@app.route('/progress')
def progress():
return Response(import_progress(), mimetype='text/event-stream')
def import_progress():
"""
Just a small example
"""
for number in range(1, 101):
sse_id = str(number)
sse_progress = str(number)
sse_event = 'import-progress'
if number == 100:
sse_event = 'last-item'
yield "id:{_id}\nevent:{event}\ndata:{progress}\n\n".format(
_id=sse_id, event=sse_event, progress=sse_progress)
我尝试了很多让重定向工作。但我不知道该怎么做。到目前为止的每一次尝试都失败了。
您要做的是将重定向 URL 作为最后一个事件发送 - 您仍然需要使用 JavaScript 进行重定向,但您不必对路径进行硬编码还有:
def import_progress():
"""
Just a small example
"""
for number in range(1, 101):
sse_id = str(number)
sse_data = str(number)
sse_event = 'import-progress'
if number == 100:
sse_event = 'last-item'
sse_data = url_for('product_list')
yield "id:{_id}\nevent:{event}\ndata:{data}\n\n".format(
_id=sse_id, event=sse_event, data=sse_data)
然后您的最后一项处理程序变为:
source.addEventListener('last-item', function(event) {
source.close();
redirect(event.data);
}, false
);
并且redirect
变得简单:
function redirect(url) {
document.location = url;
}