簡體   English   中英

Chrome瀏覽器訪問網站后,燒瓶無法處理其他HTTP請求

[英]Flask not processing other HTTP requests after Chrome browser accesses the web-site

問題陳述:當我嘗試從Chrome瀏覽器訪問不存在的文件后,我在Flask上的Web服務器未處理HTTP請求。 當Chrome關閉或訪問確實存在的頁面時,積壓的HTTP請求將立即得到處理。

影響: Web服務器可用性很差。

問題:為什么會發生這種情況,以及如何在不以線程模式運行Flask的情況下進行修復?

我在網上找到的最近的帖子是:github.com/pallets/flask/issues/2188,但是找不到完全相同的問題和解決方案。 期待您的想法-非常感謝您的幫助!

主要假設: 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()    
  • 在хттп://127.0.0.1:5000 /上運行(按CTRL + C退出)

2)確認您在瀏覽器或curl中收到“ Hello world”響應:

curl -v本地主機:5000 /

3)在Chrome瀏覽器中進入localhost:5000 / page,這表明筆記主義者在瀏覽器中觀察到“未找到”錯誤

4)重復curl -v localhost:5000 /命令

觀察已建立連接,但未收到響應,例如:

curl -v localhost:5000 / *正在嘗試:: 1 ... *連接失敗*連接到:: 1端口5000失敗:連接被拒絕*正在嘗試127.0.0.1 ... *已連接到localhost(127.0.0.1)端口5000( #0)

GET / HTTP / 1.1主機:localhost:5000用戶代理:curl / 7.49.0接受: /

5)在Chrome中轉到存在的頁面或關閉Chrome

觀察對卷曲的即時反應:

  • HTTP 1.0,假定在正文之后關閉<HTTP / 1.0 200 OK <Content-Type:text / html; charset = utf-8 <Content-Length:13 <服務器:Werkzeug / 0.11.10 Python / 3.5.1 <日期:Tue,28 Feb 2017 21:44:20 GMT <
  • 正在關閉連接0您好,世界!

重現此問題可能需要進行多種嘗試。 通常發生> 10次中的8次

其他信息:

1)代替curl,我可以使用Safari或telnet或python腳本-同樣的問題

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)[Linux上的[GCC 4.4.7 20120313(Red Hat 4.4.7-1)]

燒瓶。 版本 “ 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

更新

只要Chrome發出正常的http請求,我就可以重現該問題而不會出現404錯誤。 在Flask日志中沒有觀察到錯誤。

這是帶有問題演示視頻

另一件有趣的事情-如果在Chrome瀏覽器中使用隱身窗口,則不會出現此問題。 但是,在正常模式下清除Chrome緩存並不能解決問題。

我兩次遇到相同的問題。

相同的環境:純Flask(無反向代理),最簡單的應用程序。

使用Chrome / Chromium打開URL后,Flask將掛起,並且不會響應其他客戶端(curl,郵遞員,firefox,python-request等)。

Chrome的解決方法

在Chrome / Chromium中禁用網址預測服務選項的實際名稱在屏幕截圖中

鉻設置

真正的解決方案(用於Flask)

即將推出( 歡迎捐款! )。

啟用線程。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM