我有一个Django项目,我正在使用视图来处理不同的HTTP方法。 POST
处理了对象的创建,然后使用Django的GET
快捷方式(redirect()
)重定向到与HTTPResponseRedirect
相同的视图(我认为是这样)新创建的对象。这很好。我用PUT
尝试了同样的事情,但我陷入了重定向循环。在我搔了一会儿后,我偶然发现了this SO answer然后我推断,由于重定向不处理POST
数据,请求变成了GET
。
我通过在POST
[15/Dec/2014 00:47:43] "POST /client/151/ HTTP/1.1" 302 0
[15/Dec/2014 00:47:43] "GET /client/151/ HTTP/1.1" 200 395
然而,PUT
保持PUT
并引发我进入重定向循环,直到它出错。
[14/Dec/2014 23:07:36] "PUT /api/asset/6779 HTTP/1.1" 301 0
[14/Dec/2014 23:07:37] "PUT /api/asset/6779/ HTTP/1.1" 302 0
[14/Dec/2014 23:07:37] "PUT /api/asset/6779 HTTP/1.1" 301 0
[14/Dec/2014 23:07:38] "PUT /api/asset/6779/ HTTP/1.1" 302 0
[14/Dec/2014 23:07:38] "PUT /api/asset/6779 HTTP/1.1" 301 0
[14/Dec/2014 23:07:39] "PUT /api/asset/6779/ HTTP/1.1" 302 0
[14/Dec/2014 23:07:39] "PUT /api/asset/6779 HTTP/1.1" 301 0
[14/Dec/2014 23:07:40] "PUT /api/asset/6779/ HTTP/1.1" 302 0
[14/Dec/2014 23:07:40] "PUT /api/asset/6779 HTTP/1.1" 301 0
[14/Dec/2014 23:07:41] "PUT /api/asset/6779/ HTTP/1.1" 302 0
[14/Dec/2014 23:07:41] "PUT /api/asset/6779 HTTP/1.1" 301 0
[14/Dec/2014 23:07:42] "PUT /api/asset/6779/ HTTP/1.1" 302 0
重定向不应该使用GET
吗?我明白发生了什么,但不确定为什么?是什么给了什么?
修改
# urls.py
url(r'^$', views.put_vs_post_redirect),
# views.py
from django.shortcuts import redirect
def put_vs_post_redirect(request, asset_id):
if request.method == 'GET':
return HTTPResponse('Get request')
elif request.method == 'POST':
return redirect('/')
elif request.method == 'PUT':
return redirect('/')
答案 0 :(得分:5)
正如评论中所提到的,这完全取决于客户端,并非所有客户端都以相同的方式处理重定向。您可以在Stack Overflow上找到a decent explanation of the redirect codes和why a 301 should drop POST data。
使用301
(通常是302
)重定向时,大多数浏览器会丢弃POST
个数据并发出GET
个请求。这主要是因为浏览器始终执行此,而POST
请求最常来自Web表单,因此重定向导致GET
有意义,允许浏览器显示不同的页面而不会干扰。对于PUT
或PATCH
请求之类的情况并非如此,因为它们目前无法通过网络表单发送,并且通常按照不同的规则播放。
如果您希望维护POST
重定向的302
数据,则应考虑using a 307
redirect instead。 307
请求应该维护请求方法,结果是请求正文。
如果您希望在POST
重定向中维护301
数据,则目前a draft for a 308
status code可以像307
一样工作,但必须是永久性的。
您可以强制重定向使用a 303
redirect GET
请求。它非常像302
,但它强制请求方法始终是GET
请求。它经常在API中用于异步任务。