POST请求下Flask重定向后渲染大量数据触发连接重置问题
问题:POST请求经Flask重定向后返回大量内容时触发ERR_CONNECTION_RESET错误
现象说明
- 在POST请求流程中,通过
flask.redirect(使用307状态码)跳转后,调用flask.render_template向客户端返回大量记录时,会出现ERR_CONNECTION_RESET连接重置错误 - 若跳过重定向步骤,直接调用返回render_template的函数,无论返回数据量大小,均不会出现连接重置问题
- 当
number_records≥500时,该错误在Chromium浏览器中必现,在Firefox浏览器中随机出现
运行环境
- Python 3.10.9
- Flask 2.0.3
- Chromium 107.0.5304.121
- Firefox 108.0.1
复现代码
from flask import Flask, render_template_string, redirect, url_for # ERR_CONNECTION_RESET depends on number_records number_records = 100 # no error observed number_records = 500 number_records = 1000 # data used in templates choices = ["choice_1", "choice_2", "choice_3"] dn = {} for i in range(1, number_records+1): dn[i] = "name_%d" %(i) # flask app app = Flask(__name__) @app.route("/") def main(): tmpl1 = """ <!doctype html> <html> <head><title>Test main</title></head> <body> <hr> <form method=POST action=manage_names> <h1>Select the names</h1> <table id="t_names"> <thead> <tr> <th>Select</th> <th>name</th> </tr> </thead> {% for k, v in dn.items() %} <tbody> <tr> <td> <input type="checkbox" name="select" value="{{ k }}" checked></input> </td> <td>{{ v }}</td> </tr> </tbody> {% endfor %} <br> </table> <br> <button type=submit name=submit-button value=submit method=POST>submit</button> </form> </body> </html> """ return render_template_string(tmpl1, dn=dn) @app.route("/manage_names", methods=["POST"]) def _manage_names(): # no code for tests return redirect(url_for("_set_choices"), code=307) @app.route("/set_choices", methods=["POST"]) def _set_choices(): tmpl2 = """ <!doctype html> <html> <head><title>Test ERR_CONNECTION_RESET</title></head> <body> <hr> <form method=POST action=manage_choices><h1>Set the choices</h1> <table id="t_choices" class="choice"> <thead> <tr> <th>name</th> <th>choice</th> </tr> </thead> {% for k, v in dn.items() %} <tbody> <tr> <td>{{ v }}</td> <td> <input type="hidden" name="id" value="{{ k }}"/> <select name="choice" id="{{ k }}"> {% for c in choices %} <option>{{ c }}</option> {% endfor %} </select> </td> </tr> </tbody> {% endfor %} <br> </table> <br> <button type=submit name=submit-button value=submit method=POST>submit</button> </form> </body> </html> """ return render_template_string(tmpl2, dn=dn, choices=choices) @app.route("/manage_choices", methods=["POST"]) def _manage_choices(): # For tests return redirect("/") if __name__ == '__main__': app.run(debug=True)
内容的提问来源于stack exchange,提问作者fcpp1
相关产品推荐
相关产品推荐

