python-requests 发出 GET 而不是 POST 请求
Posted
技术标签:
【中文标题】python-requests 发出 GET 而不是 POST 请求【英文标题】:python-requests making a GET instead of POST request 【发布时间】:2015-06-11 06:15:55 【问题描述】:我有一个每日 cron 来处理我的应用程序中的一些重复事件,我不时注意到日志中弹出一个奇怪的错误。除其他外,cron 对一些代码进行验证,它使用在同一服务器上运行的 webapp,因此验证请求是通过带有一些数据的 POST
请求发出的。
url = 'https://example.com/validate/'
payload = 'pin': pin, 'sku': sku, 'phone': phone, 'AR': True
validation_post = requests.post(url, data=payload)
所以,这发出了实际的请求,我记录了响应。有时,最近多达 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>
因此,实际请求是使用 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"
应用程序的 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)
所以,一切都表明实际请求不是使用 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)
应用程序路由可能失败,try
块内有一些 returns
,但即使这些失败或有异常,也没有什么可以引发此块中的 405
错误代码,只有 403
很少发生,因为我从 cron 手动构建和登录用户。
我发现了类似的东西here,但是有一个从 HTTP 到 HTTPS 版本的重定向,我在服务器中也有该重定向,但是发出请求的 URL 包含 HTTPS它,所以我怀疑这是原因。
我运行它的堆栈是uwsgi
+nginx
+flask
。谁能看到可能导致这种情况的原因?重复一遍,它并不总是发生,所以有时它按预期工作,有时不是。我最近从apache
和mod_wsgi
迁移到这个新堆栈,从那时起我开始遇到这个错误;不记得曾经在apache
环境中看到过它。
谢谢!
【问题讨论】:
【参考方案1】:我们唯一一次将POST
请求更改为GET
是在我们处理重定向时。根据重定向代码,我们将更改请求方法。如果您想确保我们不遵循重定向,您需要传递allow_redirects=False
。也就是说,您需要弄清楚您的应用程序生成重定向的原因(包括它是重定向到 HTTP 还是重定向到不同的域,或者使用特定的状态代码)。
【讨论】:
感谢您的回复。我已经用这个标志修改了我的应用程序中的调用,并添加了一些调试信息来尝试看看是什么原因造成的。 我知道发生这种情况似乎很烦人,但我想向您保证,我们正在做的是当前处理重定向的最佳实践。请求中发生的事情是为了您的安全。以上是关于python-requests 发出 GET 而不是 POST 请求的主要内容,如果未能解决你的问题,请参考以下文章
python - requests.get (Connection aborted.', OSError("(60, 'ETIMEDOUT')