【问题标题】:Django comments - Ajax and CSRF failureDjango 评论 - Ajax 和 CSRF 失败
【发布时间】:2011-09-28 16:37:35
【问题描述】:

我认为这与这里的其他问题不同,我已经检查了答案,但仍然没有运气。感谢您的帮助:

我有一个新闻项目列表(如 facebook 提要),每个项目都附有评论表(使用 django.contrib.cmets 应用程序)。可以正常使用。

但是,我在页面上使用了一种 AJAX“无限滚动”——当您滚动时,它会通过 AJAX 加载下一组新闻项目和相关评论表单。新加载的新闻项目的评论表单不起作用(CSRF 验证失败)。

原因很明显 - {% csrf_token %} 没有传递给返回的 JSON 响应,因此新加载的评论表单没有 CSRF 数据。

我尝试在 Django 页面 (https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/#ajax) 上使用 set cookie 方法,但似乎没有用,也没有确实尝试使用 @csrf_exempt 装饰器来完全排除 CSRF。

有什么建议可以将 csrf_token 与返回的 JSON 响应一起传递吗?或者有其他选择吗?

这是视图:

def my_view(request):
    # the normal view gets a queryset of all Info items and returns them
    infos = Info.objects.all()
    ....

    # here's the AJAX part
    if request.GET.get('xhr') and page > 1:
        infos = paginator.page(int(request.GET.get('page')))
        objects_list = []
        for object in infos:
            objects_list.append(render_to_string('list/snippets/feed_li.html', {
                'object': object,
            }))

        json =  simplejson.dumps(objects_list, cls=DjangoJSONEncoder)
        return HttpResponse(json, mimetype='application/json')

【问题讨论】:

    标签: jquery ajax django json csrf


    【解决方案1】:

    一种选择是通过您返回的 JSON 响应向您的表单提供 CSRF 令牌。我相信您可以通过调用 django.middleware.csrf.get_token(request) 以编程方式获取 CSRF 令牌,然后将该值包含在您的 ajax 响应中。

    我能想到的另一个选项是禁用该视图的 CSRF 保护。

    【讨论】:

      【解决方案2】:

      首先检查您是否忘记在 'list/sn-ps/feed_li.html' 中包含 {% csrf_token %};

      其次,要使csrf令牌正常工作,必须使用RequestContext或手动生成令牌并在渲染模板时将其添加到上下文变量中(参见Django csrf ref)。因此,替换行:

      objects_list.append(render_to_string('list/snippets/feed_li.html', {
          'object': object,
      }))
      

      与:

      ''' from django.template import RequestContext ''' 
      objects_list.append(render_to_string('list/snippets/feed_li.html', \
          RequestContext(request, {'object':object})
      ))
      

      或:

      ''' from django.core.context_processors import csrf '''
      vars = {}
      vars.update(csrf(request))
      vars.update({'object':object})
      objects_list.append(render_to_string('list/snippets/feed_li.html', vars))
      

      【讨论】:

        猜你喜欢
        • 2012-04-16
        • 2012-01-10
        • 2020-03-24
        • 2016-03-20
        • 2016-01-04
        • 2013-05-26
        • 2011-07-03
        • 2015-06-21
        相关资源
        最近更新 更多