python-requests 发出 GET 而不是 POST 请求

won*_*ile 3 python nginx http-status-code-405 uwsgi python-requests

我有一个每日 cron 来处理我的应用程序中的一些重复事件,我不时注意到日志中弹出一个奇怪的错误。除其他外,cron 会对一些代码进行验证,并且它使用运行在同一服务器上的 web 应用程序,因此验证请求是通过POST带有一些数据的请求发出的。

url = 'https://example.com/validate/'
payload = {'pin': pin, 'sku': sku, 'phone': phone, 'AR': True}
validation_post = requests.post(url, data=payload)
Run Code Online (Sandbox Code Playgroud)

所以,这会产生实际的请求,我会记录响应。有时,最近高达 50% 的请求,响应包含来自 nginx 的以下消息:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>405 Method Not Allowed</title>
<h1>Method Not Allowed</h1>
<p>The method GET is not allowed for the requested URL.</p>
Run Code Online (Sandbox Code Playgroud)

因此,实际请求是使用GET方法发出的,而不是代码中指示的POST。在 nginx 中,access.log我可以看到该条目:

123.123.123.123 - - [18/Feb/2015:12:26:50 -0500] "GET /validate/ HTTP/1.1" 405 182 "-" "python-requests/2.2.1 CPython/2.7.6 Linux/3.13.0-37-generic"
Run Code Online (Sandbox Code Playgroud)

该应用程序的 uwsgi 日志显示了类似的内容:

[pid: 6888|app: 0|req: 1589/58763] 123.123.123.123 () {40 vars in 613 bytes} [Mon Apr  6 11:42:41 2015] GET /validate/ => generated 182 bytes in 1 msecs (HTTP/1.1 405) 4 headers in 234 bytes (1 switches on core 0)
Run Code Online (Sandbox Code Playgroud)

因此,一切都表明实际请求不是使用POST发出的。处理这段代码的应用路由很简单,摘录如下:@app.route('/validate/', methods=['POST']) @login_required

def validate():
    if isinstance(current_user.user, Sales):
        try:
            #do the stuff here
        except Exception, e:
            app.logger.exception(str(e))
            return 0
    abort(403)
Run Code Online (Sandbox Code Playgroud)

应用程序路由可能会失败,并且块returns内有一些try,但即使这些失败或存在异常,也没有任何东西可以引发405此块中的错误代码,403这很少发生,因为我手动构建和登录用户从 cron。

我在这里发现了类似的东西但问题是存在从 HTTP 到 HTTPS 版本的重定向,而且服务器中也存在该重定向,但是发出请求的 URL 中包含 HTTPS,所以我怀疑这就是原因。

我正在运行的堆栈是uwsgi+ nginx+ flask。任何人都可以看到可能导致这种情况的原因吗?重复一遍,它并不总是发生,所以有时它会按预期工作,有时不会。我最近从迁移apachemod_wsgi这个新的堆栈,从这一点我已经开始encontering这个错误; 不记得曾经在apache环境中看到过它。

谢谢!

Ian*_*sco 5

我们唯一一次将POST请求更改为 aGET是在处理重定向时。根据重定向代码,我们将更改请求方法。如果您想确保我们不遵循重定向,您需要通过allow_redirects=False. 也就是说,您需要弄清楚应用程序生成重定向的原因(包括它是否重定向到 HTTP 或其他域,或使用特定状态代码)。