Django - 即使设置了CSRF令牌,手机上的Ajax请求也会被禁止403

时间:2015-10-02 02:07:10

标签: jquery ajax django http-status-code-403

我无法在移动平台上测试我使用django开发的网站。我设置了我的服务器,以便在滚动时使用javascript从django视图中使用ajax连续加载帖子。

当我从命令行运行我的服务器并在桌面浏览器上测试它时,该服务运行良好,我的帖子连续加载,没有任何403禁止错误。但是,当我尝试在手机上测试时,我可以在服务器的命令输出中看到请求已被给予403禁止响应。

我不确定可能导致这种情况发生的任何事情,因为我已经考虑到在进行ajax调用之前需要加载csrf令牌。

以下是我用来加载csrf令牌的代码。

$(document).ready(function () {
  function getCookie(name) {
      var cookieValue = null;
      if (document.cookie && document.cookie != '') {
          var cookies = document.cookie.split(';');
          for (var i = 0; i < cookies.length; i++) {
              var cookie = jQuery.trim(cookies[i]);
              if (cookie.substring(0, name.length + 1) == (name + '=')) {
                  cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                  break;
              }
          }
      }
      return cookieValue;
  }
  var csrftoken = getCookie('csrftoken');
  function csrfSafeMethod(method) {
      return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
  }
  $.ajaxSetup({
      beforeSend: function(xhr, settings) {
          if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
              xhr.setRequestHeader("X-CSRFToken", csrftoken);
          }
      }
  });

});

以下是通过ajax连续调用的视图的代码。

# Get a post item
def get_posts (request):
    # Catch any errors
    try:
        # Request for home post
        if request.POST['type'] == 'home':
            # Post index to fetch
            index = int(request.POST['index'])
            # Fetch the post of the specified index
            posts = HomePost.objects.all()
            # Specified index does not exist
            if index >= len(posts):
                # 400 client error response
                return HttpResponse(status='400')
            # Template the post into an html string, cut off './' from image url
            post_html = render_to_string('home_post.html', {'image': str(posts[index].image)[2:], 'body': posts[index].body});
            # Return the templated post html
            return HttpResponse(post_html)
    # Error while parsing
    except:
        # 500 internal server error response
        return HttpResponse(status='500')

编辑:

我已经对哪些特定的浏览器导致同样的问题进行了进一步的测试,我得出的结论是,chrome桌面是唯一没有此问题的浏览器。

1 个答案:

答案 0 :(得分:2)

使用@ensure_csrf_cookie装饰器。

来自docs

  

Page使用AJAX而不使用任何HTML表单

     

页面通过AJAX发出POST请求,并且该页面没有带有csrf_token的HTML&gt;表单,这将导致所需的CSRF cookie被&gt;发送。

     

解决方案:在发送页面的视图上使用ensure_csrf_cookie()。