为什么Django的HTTPResponseRedirect对PUT使用相同的HTTP方法但不使用POST?

时间:2014-12-15 05:52:48

标签: python django http http-status-code-301 http-status-code-302

我有一个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('/')

1 个答案:

答案 0 :(得分:5)

正如评论中所提到的,这完全取决于客户端,并非所有客户端都以相同的方式处理重定向。您可以在Stack Overflow上找到a decent explanation of the redirect codeswhy a 301 should drop POST data

使用301(通常是302)重定向时,大多数浏览器会丢弃POST个数据并发出GET个请求。这主要是因为浏览器始终执行此,而POST请求最常来自Web表单,因此重定向导致GET有意义,允许浏览器显示不同的页面而不会干扰。对于PUTPATCH请求之类的情况并非如此,因为它们目前无法通过网络表单发送,并且通常按照不同的规则播放。

如果您希望维护POST重定向的302数据,则应考虑using a 307 redirect instead307请求应该维护请求方法,结果是请求正文。

如果您希望在POST重定向中维护301数据,则目前a draft for a 308 status code可以像307一样工作,但必须是永​​久性的。

您可以强制重定向使用a 303 redirect GET请求。它非常像302,但它强制请求方法始终是GET请求。它经常在API中用于异步任务。