烧瓶中没有POST请求和Content-Type"application/json"的响应

Mar*_*coq 3 python post json http-headers flask

我遇到了Flask视图的问题,该视图应该返回内容类型为"application/json"的响应以响应POST请求.具体来说,如果我这样做:

curl -v -d 'foo=bar' http://example.org/jsonpost
Run Code Online (Sandbox Code Playgroud)

对此观点:

@app.route('/jsonpost', methods=['GET', 'POST'])
def json_post():
    resp = make_response('{"test": "ok"}')
    resp.headers['Content-Type'] = "application/json"
    return resp
Run Code Online (Sandbox Code Playgroud)

我得到某种连接重置:

* About to connect() to example.org port 80 (#0)
*   Trying xxx.xxx.xxx.xxx... connected
* Connected to example.org (xxx.xxx.xxx.xxx) port 80 (#0)
> POST /routing/jsonpost HTTP/1.1
> User-Agent: curl/7.19.7 (i486-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
> Host: example.org
> Accept: */*
> Content-Length: 7
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 200 OK
< Server: nginx/1.2.4
< Date: Thu, 27 Dec 2012 14:07:59 GMT
< Content-Type: application/json
< Content-Length: 14
< Connection: keep-alive
< Set-Cookie: session="..."; Path=/; HttpOnly
< Cache-Control: public
<
* transfer closed with 14 bytes remaining to read
* Closing connection #0
curl: (18) transfer closed with 14 bytes remaining to read
Run Code Online (Sandbox Code Playgroud)

如果相反,我做:

curl -d 'foo=bar' http://example.org/htmlpost
Run Code Online (Sandbox Code Playgroud)

至:

@app.route('/htmlpost', methods=['GET', 'POST'])
def html_post():
    resp = make_response('{"test": "ok"}')
    resp.headers['Content-Type'] = "text/html"
    return resp
Run Code Online (Sandbox Code Playgroud)

我得到了预期的完整回复(200-ok)

{"test": "ok"}
Run Code Online (Sandbox Code Playgroud)

顺便说一下,如果我向同一个JSON路由发送GET请求:

curl http://example.org/jsonpost
Run Code Online (Sandbox Code Playgroud)

我也得到了预期的回应..任何想法?

Mar*_*coq 11

感谢Audrius的评论,我跟踪了uWSGI和nginx之间交互的问题的可能来源:显然,如果您在请求中收到POST数据,则必须在返回响应之前阅读它.

例如,这解决了我的问题.

@app.route('/jsonpost', methods=['GET', 'POST'])
def json_post():
    if request.method == 'POST':
        dummy = request.form
    resp = make_response('{"test": "ok"}')
    resp.headers['Content-Type'] = "application/json"
    return resp
Run Code Online (Sandbox Code Playgroud)

根据uWSGI的作者Roberto De Ioris的--post-buffering 1描述,一种解决方案是传递给uWSGI.

我仍然不明白为什么问题不会出现在Content-Type设置中"text/html"