我有以下代码
def ajax_login_request(request): try: request.POST[u'login'] dictionary = request.POST except: dictionary = request.GET user = authenticate(username = dictionary[u'login'], password = dictionary[u'password']) if user and user.is_active: login(request, user) result = True else: result = False response = HttpResponse(json.dumps(result), mimetype = u'application/json') return response
这是通过ajax调用的.我是一个菜鸟,这是一本书的例子.不幸的是,我正在使用的Django版本会引发CSRF错误.我已经完成了其他CSRF位,但我不知道如何将HttpResponse位更改为渲染调用.我不想使用CSRF_exempt,因为我不知道什么时候合适.有人可以请给我上面的HttpResponse等效的渲染调用.
谢谢
好的,我将重新起草这个答案,以便你了解我的来源.CSRF中间件的工作方式如下:
You make request -------> request hits csrf --(invalid/no token)--> render 403 middleware | (valid token) | \ / Call view | \ / middleware sets csrf cookie | \ / Response appears
换句话说,如果您看到403 csrf页面,则从未调用过您的视图.您可以通过在视图中粘贴虚假打印语句并runserver
在发出请求时观察输出来确认这一点.
要解决此问题,您需要禁用csrf(不好)或使用其中一种可用的ajax方法.如果在视图中传递了所需的标记,则实际将执行.
未调用视图的原因是为了防止伪造站点的操作实际发生 - 例如,如果在响应时拒绝模板,则用户已经登录.功能装饰器也会出现相同的行为.
至于设置cookie的中间件,它根本不会改变或依赖于渲染功能 - 这会Cookie: ...
在响应中设置HTTP头.Django中的所有响应都是HttpResponse
对象,直到它最终将它们转换为输出; render
函数是助手,但这不是导致你的问题的原因.
编辑我会将您所拥有的内容转换为渲染调用.你可以这样做:
return render_to_response(`ajax_templates/login_response.html`, {'loginresponse': json.dumps(result)})
在哪里ajax_templates/login_response.html
:
{% loginresponse %}
而已.HttpResponse
有一个主要的默认参数,它是要返回的字符串(字面意思是网页的html); 这就是你最初做的事情.render_to_response
并且render
是执行此操作的快捷方式:
render_to_response called ----> open template asked for --> substitute arguments | \ / django instructs web server <--- return this from view <-- create HttpResponse to send to client object
要使原始代码有效,您需要获取一个RequestContext对象并将其与您的响应一起传递,如下所示:
from django.http import HttpResponse from django.template import RequestContext, Template def ajax_login_request(request): # ... # This bit of code adds the CSRF bits to your request. c = RequestContext(request,{'result':json.dumps(result)}) t = Template("{{result}}") # A dummy template response = HttpResponse(t.render(c), mimetype = u'application/json') return response
请阅读CSRF文档,因为如果您不了解CSRF在您的应用中"有线"的所有方式,您可能会遇到奇怪的错误.该页面还有一个javascript代码段,以确保在没有表单的情况下发送CSR请求时,如果您发送了CSR错误请求.
您也可以使用render_to_response()快捷方式,但是您需要加载一个实际模板(在您的情况下,您不需要模板,因此在我的示例中为"虚拟"模板).