【发布时间】:2014-05-13 19:52:54
【问题描述】:
我正在将我的项目移植到 Django Rest Framework 以便为我的项目制作适当的 REST Api,我认为这有助于设计 API 并使其健壮,但我遇到了一个问题:
我有一个入门模型和关联的ListCreateAPIView 和RetrieveUpdateDestroyAPIView 视图。
我可以通过 ajax 请求成功地在列表中发布一个新条目实例,并提供 csrfmiddlewaretoken,就像我在常规 Django 视图中所做的那样。
POST entries/
现在我正在尝试使用相同的 csrfmiddlewaretoken 将补丁应用到现有实例,如下所示:
PATCH entries/3
然后响应状态代码是 403 FORBIDDEN vith error CSRF Failed: CSRF token missing or incorrect 尽管我在 firebux 中检查了 csrfmiddlewaretoken 在请求数据中。
我不知道有什么问题,我无法找出代码中的哪个请求被拒绝。
注意:我可以使用 Django Rest Framework 可浏览 api 修补对象。
我希望有人可以提供帮助。 谢谢。 奥利维尔
编辑
我正在深入研究代码以查看 PATCH 请求被拒绝的位置,我在django.middleware.csrt.py 中发现了以下内容:
if csrf_token is None: #<--- csrf_token is defined
# No CSRF cookie. For POST requests, we insist on a CSRF cookie,
# and in this way we can avoid all CSRF attacks, including login
# CSRF.
return self._reject(request, REASON_NO_CSRF_COOKIE)
# Check non-cookie token for match.
request_csrf_token = ""
if request.method == "POST": #<--- This fails but request_csrf_token is in request.DATA
request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
if request_csrf_token == "":
# Fall back to X-CSRFToken, to make things easier for AJAX,
# and possible for PUT/DELETE.
request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')
第二个测试失败,因为它不是 POST 请求,但所需的信息在 request.DATA 中。 所以看来 django 并不热衷于接受 PATCH 请求。 您认为解决此问题的最佳方法是什么?
您是否建议使用不同的身份验证系统(在 Django-rest-framework 文档中有一些)?
EDIT2
我找到了一个解决方案: 我观察到可浏览的 api 实际上是发送一个 POST 请求,但带有一个参数 _method="PATCH",所以我对我的 ajax 请求做了同样的事情,它工作正常。
我不知道这样做是否正确,欢迎任何反馈和意见!
EDIT3
所以,在阅读更多之后,我发现(我已经有点知道了..)因为一些浏览器不支持 PUT、PATCH、DELETE 等请求,所以要走的路是使用 X-HTTP- 发送一个 post 请求标题中的方法覆盖。
所以我认为最好的方法是执行以下操作:
$.ajax({
headers: {
'X-HTTP-Method-Override': 'PATCH'
},
type : "POST",
...
});
【问题讨论】:
标签: ajax django rest django-rest-framework