Flask post / redirect / get模式无法从错误中恢复
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask post / redirect / get模式无法从错误中恢复相关的知识,希望对你有一定的参考价值。
我在Flask视图函数中有一个错误恢复问题。它的简化版本在这里:
@app.route('/log', methods=['POST', 'GET'])
def elog():
form = LogForm()
if form.validate_on_submit():
flask.session['logformdata'] = form.data
return flask.redirect(flask.url_for('elog'))
try:
formdata = flask.session.pop('logformdata')
except KeyError:
return flask.render_template('log.html', form=form)
log = ... # result of a query
form.process(data=formdata)
return flask.render_template('log.html', form=form, log=log)
重要的是它实现了post / redirect / get模式,并将表单数据存储在使用HTTP cookie实现的flask.session
存储中的POST和GET之间。
现在让我们假设某处有一个错误,并且该函数在某些输入时崩溃。当然,它不应该发生。但是当它发生时,用户的体验非常糟糕。
详细地:
- 用户发布表单(POST)
- 表格数据存储在
flask.session
中,即作为cookie - 重定向后,再次调用该函数(GET),但现在它意外崩溃。用户看到一些错误消息。这不好,但是错误发生了。
- 用户重新加载想要重新开始的页面,但一次又一次地重复出现相同的错误!
关键点是语句flask.session.pop
从session
存储中删除表单数据,但是当函数崩溃时,相应的cookie仍保留在用户的浏览器中。每次重新加载都会再次触发错误。重新启动浏览器可能会有所帮助(取决于session.permanent
标志)。唯一有保障的补救措施是手动从浏览器中删除cookie。这有效地使网页无法使用。
我想我可以通过设置非常短的cookie生命周期(大约15秒)或通过在每次重启后生成新的密钥来缓解这个问题。我没有尝试过,如果会话cookie包含其他数据,那绝对不是一个好的解决方案。
如何使上述功能更强大?
如果在视图本身内无法处理错误,我的方法是针对整个应用程序使用register an error handler,并在此处管理会话,即重置为默认/安全状态。
例:
@app.errorhandler(500)
def handle_internal_server_error(ex):
"""Handle an unexpected and uncaught (500) server error."""
# Reset session here & display error (e.g. flash or other)
return # redirect or render
我认为你的简化示例错过了一个重要的部分来表示究竟崩溃的原因。
如果某些逻辑可能意外崩溃,那么你应该期望它能够这样做并处理这些情况。例如,通过将其包装在通常的try/catch
中并删除catch块中的会话cookie。
您正在手动管理会话,这导致此问题。请查看在您的应用程序中实现Message Flashing。您可以自定义闪存以使用服务器端会话甚至使用cookie。即使使用重定向,也可以跨多个页面维护Flash消息。
以上是关于Flask post / redirect / get模式无法从错误中恢复的主要内容,如果未能解决你的问题,请参考以下文章
Flask 中的 Render Redirect HttpResponse
Flask 中的 Render Redirect HttpResponse
Flask最强攻略 - 跟DragonFire学Flask - 第二篇 Flask 中的 Render Redirect HttpResponse