Chrome浏览器访问网站后Flask不处理其他HTTP请求

jjjwad0x  于 2022-12-06  发布在  Go
关注(0)|答案(2)|浏览(309)
  • 问题陈述:* 在我尝试从Chrome浏览器访问不存在的文件后,Flask上的Web服务器无法处理HTTP请求。当Chrome关闭或访问确实存在的页面时,会立即处理积压的HTTP请求。
  • 影响:* Web服务器可用性差。
  • 问题:* 为什么会发生这种情况,如何在不以线程模式运行Flask的情况下修复它?

The closest post I found online is this: github.com/pallets/flask/issues/2188 but could not find exactly the same problem and solution. Looking forward to your thoughts - thanks so much for your help!

  • 主要假设:* Chrome没有读取404响应的所有内容,Flask正在等待读取所有内容
    • 详细数据:**
  • 重现问题的步骤:*

1)运行最小 flask 应用程序(http://flask.pocoo.org/docs/0.12/quickstart/):

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

app.run()
  • Running on хттп://127.0.0.1:5000/ (Press CTRL+C to quit)

2)验证您是否在浏览器或curl中得到"Hello world"响应:
curl-v本地主机:5000/
3)在Chrome浏览器中,转到localhost:5000/pagethatdoesnotexists,在浏览器中观察到"未找到"错误
4)重复curl-v本地主机:5000/命令
观察到连接已建立但未收到响应,例如:
curl-v localhost:5000/正在尝试::1 ... * 连接失败 * 连接到::1端口5000失败:连接被拒绝 * 正在尝试127.0.0.1 ... * 已连接到本地主机(127.0.0.1)端口5000(#0)
GET/HTTP/1.1主机:本地主机:5000用户代理: curl /7.49.0接受:
/*
5)在Chrome浏览器中,转到存在的页面或关闭Chrome浏览器
观察对 curl 的即时响应:

  • HTTP 1.0,假设在正文之后关闭〈HTTP/1.0 200 OK〈内容类型:文本/html;字符集= utf-8〈内容长度:13〈服务器:工具/0.11.10 Python/3.5.1〈日期:2017年2月28日星期二格林尼治标准时间21:44:20〈
  • 正在关闭连接0 Hello,World!

可能需要多次尝试才能重现问题。通常10次中有8次以上发生

    • 其他信息:**

1)我可以使用Safari或telnet或python脚本来代替curl-同样问题
2)Safari不会产生问题,而Chrome会
3)我试图通过发送与Chrome完全相同的http请求来模仿Chrome,但无法重现问题。Chrome可能会做其他事情。
4)当我在线程模式下运行Flask(用不同的线程处理每个请求)时,问题就消失了。
5)版本:
Chrome版本56.0.2924.87(64位)
Python 3.5.2语言|Anaconda 4.1.1(64位)|(默认值,2016年7月2日17:53:06)[愚者4.4.7 20120313(红帽4.4.7 - 1)]在Linux上运行
flask 版本'0.11.1'
6)AWS Ubuntu生产服务器计算机上也会出现此问题
7)尝试在404 http响应中发送自定义标题,但没有成功

@app.errorhandler(404)
def page_not_found(e):
    # return render_template('404.html'), 404
    resp = make_response(render_template('404.html'), 404)
    # resp.headers['Connection'] = 'close'
    resp.headers['Cache-Control'] = 'no-cache, no-store'
    return resp
    • 更新**

我能够重现这个问题,没有404错误,只是从Chrome的正常http请求。在Flask日志中没有观察到任何错误。
这里是video with the problem demonstration
另一个有趣的事情-如果在Chrome浏览器中使用隐姓埋名的窗口,这个问题是不会被观察到的。然而,在正常模式下清除缓存Chrome并不能解决这个问题。

ktecyv1j

ktecyv1j1#

启用线程。

app.run(host='0.0.0.0', port=80, debug=True, threaded=True)

TL;DR

这个问题仍然存在。当页面预取被启用时,Chrome似乎没有关闭连接,它阻止了服务器的执行,从而阻止了后续请求的处理。
在我的情况下,问题甚至最糟糕,因为基于Android的手机也使用这种预取功能与相同的结果,我不能改变每个客户端的设置。
我的解决方案/变通方法是在底层werkzeug服务器(https://werkzeug.palletsprojects.com/en/0.16.x/serving/#werkzeug.serving.run_simple)中启用threading选项。当然,这在服务器端会占用更多的资源,但它允许我们将行为不正常的请求/客户端分离到一个单独的线程中,而不会阻塞其他请求。

if __name__ == '__main__':
    logger.info('starting web server life cycle')
    app.run(host='0.0.0.0', port=80, debug=True, threaded=True)

我还检查了请求处理是否正确完成,至少在Flask端是这样的。所以问题一定是在Chrome /其他客户端或者底层的werkzeug服务器上。

@app.before_request
def filter_prefetch():
    logger.debug("before request")
    logger.debug(request.headers)
# uncomment these to filter Chrome specific prefetch requests.
#    if 'Purpose' in request.headers and request.headers.get('Purpose') == 'prefetch':
#        logger.debug("prefetch requests are not allowed")
#        return '', status.HTTP_403_FORBIDDEN

@app.after_request
def debug_after(response):
    logger.debug("after request")
    response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
    response.headers["Pragma"] = "no-cache"
    response.headers["Expires"] = "0"
    response.headers['Cache-Control'] = 'public, max-age=0'
    response.headers['Connection'] = 'close'
    return response
db2dz4w8

db2dz4w82#

同样的问题我已经遇到两次了。
相同的环境:纯Flask(无反向代理),最简单的应用程序。
在你用Chrome/Chromium打开URL后-- Flask将挂起,不会响应其他客户端(curl、postman、firefox、python-request等)。

Chrome的解决方法

在Chrome/Chromium中禁用URL预测服务(* 选项的实际名称见屏幕截图 *)

真实的溶液( flask )

即将到来-贡献是受欢迎的!(* 最有可能我永远不会解决这个 *)。

相关问题