向自身发送 post 请求时 Flask 挂起 [英] Flask hangs when sending a post request to itself

查看:36
本文介绍了向自身发送 post 请求时 Flask 挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从我的 Flask 应用程序自己的一个视图中向我的 Flask 应用程序发送一个发布请求,但它挂起,直到我杀死服务器.如果我用 JavaScript 执行请求,它工作正常.为什么它在 Python 代码中不起作用?

I'm trying to send a post request to my Flask app from one of its own views, but it hangs until I kill the server. If I do the request in JavaScript, it works fine. Why does it not work from the Python code?

from flask import Blueprint, render_template, abort, request, Response, session, url_for
from jinja2 import TemplateNotFound

from flask.ext.wtf import Form
from wtforms import BooleanField, TextField, PasswordField

import requests

login = Blueprint('login', __name__, template_folder='templates')

class LoginForm(Form):
    email = TextField('Email')
    password = PasswordField('Password')

@login.route('/login', methods=['GET', 'POST'])
def _login():

    form = LoginForm(request.form, csrf_enabled=False)

    if form.validate_on_submit():
        return requests.post(request.url_root + '/api/login', data={"test": True})
    
    return render_template('login.html', form=form)

推荐答案

在 1.0 之前,Flask 的开发服务器默认是单线程的.在这种模式下,它一次只能处理一个请求.发出请求会阻塞,直到收到响应.您的 Flask 代码在一个线程中发出请求,然后等待.没有其他线程来处理第二个请求.所以请求永远不会完成,原始请求永远等待.

Prior to 1.0, Flask's development server was single-threaded by default. In that mode, it can only handle one request at a time. Making a request blocks until it receives the response. Your Flask code makes a request in the one thread, and then waits. There are no other threads to handle this second request. So the request never completes, and the original request waits forever.

在开发服务器中启用线程以避免死锁并修复直接问题.

Enable threads in the dev server to avoid the deadlock and fix the immediate problem.

app.run(threaded=True)

但是,从应用程序内部向应用程序发出完整的 HTTP 请求应该是不必要的,这表明存在更深层次的设计问题.例如,观察内部请求将无法访问客户端浏览器上的会话.提取公共代码并在内部调用它,而不是发出新的请求.

However, making a full HTTP request to the app from within the app should never be necessary and indicates a deeper design issue. For example, observe that the internal request will not have access to the session on the client's browser. Extract the common code and call it internally, rather than making a new request.

def common_login(data):
    ...

@app.route("/login")
def login():
    ...
    common_login(data)
    ...

@app.route("/api/login")
def api_login():
    ...
    common_login(data)
    ...

这篇关于向自身发送 post 请求时 Flask 挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆