2015-01-16 23 views
5

Tôi đang cố gắng viết một yêu cầu AJAX rất cơ bản ở Django và tôi tiếp tục nhận được lỗi 403 bị cấm trong cả bảng điều khiển Chrome Dev và Django. Tôi đã đăng một câu hỏi tương tự vào ngày hôm trước và đã thử tất cả các giải pháp được đề xuất bao gồm @csrf_exempt (để loại trừ nếu điều này thậm chí là vấn đề csrf), tôi đã thử bao gồm csrfmiddlewaretoken: '{{csrf_token}}' trong yêu cầu POST của AJAX (bên dưới dữ liệu), điều này cũng không giải quyết được vấn đề. Đây là mã của tôi.Tại sao tôi bị lỗi 403 Cấm khi sử dụng @csrf_exempt trong yêu cầu AJAX?

def profile_listview(request, username, 
    template_name=userena_settings.USERENA_PROFILE_DETAIL_TEMPLATE, 
    extra_context=None, **kwargs): 
    user = get_object_or_404(get_user_model(), 
          username__iexact=username) 
    fullsalelist = Entry.objects.filter(author__username__iexact=username) 

    @csrf_exempt 
    def delete_object(request): 
     if request.is_ajax(): 
      print "request is ajax" 
      object_name = request.POST.get('entryname') 
      targetobject = Entry.objects.get(headline=object_name) 
      if request.user.username == targetobject.author: 
       targetobject.delete() 
       print "hello" 
      return HttpResponseRedirect('/storefront/') 

Và mã AJAX trong mẫu:

<script type="text/javascript"> 
    var my_app = { 
     username: "{{ request.user.username }}" 
    }; 
</script> 

<script> 
$(document).ready(function() { 
    $(".delete_button").click(function() { 
     var id = $(this).attr('id'); 
     $.ajax({ 
      type: "POST", 
      url: "/accounts/" + my_app.username + "/listview/", 
      data: { entryname:id }, 
     }); 
     return false; 
    }); 
}); 
</script> 

URL

(r'^accounts/(?P<username>[\@\.\w-]+)/listview/$', profile_listview), 

Những điều đáng chú ý: middleware

  1. Tôi đã CSRF bật trong cài đặt của tôi

  2. bên trong mã AJAX jQuery, url và dữ liệu đều gửi thông tin chính xác

  3. Khi tôi nhấp vào nút xóa, tôi nhận được lỗi 403 bị cấm.

  4. In "yêu cầu ajax" không in trong bảng điều khiển (hoặc bất kỳ đâu).

Tôi cũng bối rối vì tôi đang nhận được thông tin xung đột. Tôi đã nói rằng tôi nên thêm giá trị csrf qua javascript (https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/). Điều này khiến tôi có 2 câu hỏi. 1. Điều này khác gì so với việc thêm csrfmiddlewaretoken: '{{csrf_token}}' vào yêu cầu POST của tôi? và 2. Quan trọng hơn, không phải thực tế là tôi vẫn gặp lỗi 403 khi sử dụng @csrf_exempt làm cho điểm này trở thành điểm tranh luận?

+0

Nhưng bạn không gửi mã thông báo csrf trong yêu cầu của mình. –

+0

Việc thêm trình trang trí csrf_exempt sẽ loại bỏ hạn chế đó, nhưng thật kỳ lạ khi 403 sẽ được trả lại. – Brandon

+0

Trên một lưu ý khác, mã JavaScript của bạn sẽ không thể xử lý 'HttpResponseRedirect' phía máy chủ.Bạn sẽ cần phải chuyển nó trở lại như một chuỗi và sau đó làm: 'top.location = json.redirect_url' chẳng hạn. – Brandon

Trả lời

0

Để hiểu biết của tôi, delete_object là một chức năng bên trong profile_listview, nhưng profile_listview không gọi nó. Do đó, profile_listview không có phản hồi http. Đăng thông báo lỗi

+0

Tôi đã kết thúc việc di chuyển biểu mẫu công cụ AJAX delete_object sang profile_listview. Vì vậy, tôi vừa loại bỏ hàm delete_object và đặt tất cả nó vào một hàm. – stephan

0

catavaran cho rằng bạn đã gọi sai chế độ xem. Bạn nên gọi chế độ xem delete_object. Ví dụ, thêm URL

(r'^accounts/(?P<username>[\@\.\w-]+)/listview/delete_object$', delete_object) 

Và AJAX

$.ajax({ 
     type: "POST", 
     url: "/accounts/" + my_app.username + "/listview/delete_object", 
     data: { entryname:id }, 
    }); 

Tôi hy vọng rằng sẽ giúp

+0

Làm cho tinh thần, nhưng delete_object hiện đang INSIDE hồ sơ_listview phương pháp, do đó, nên hoạt động đúng? Hay không. – stephan

+0

Điều đó sẽ phù hợp với một số loại quan điểm chung mà tôi nghĩ. Nhưng đó không phải là một cái nhìn chung chung. Tôi không thể hiểu cách django của bạn xử lý các chức năng delete_object. Nếu đó là công việc bạn có thể cung cấp bài viết nơi mô tả cách tạo khung nhìn – dyus

1

@csrf_exempt cần phải trước hàm được gọi bởi urls.py. Trong ví dụ của OP, delete_object không bao giờ được gọi vì lỗi đã xảy ra khi gọi profile_listview không có trình trang trí.

Lưu ý phụ, người ta có thể có tình huống tương tự (sử dụng @csrf_exempt nhưng nhận 403) nếu URL không tồn tại. Đối với một số lý do (bảo mật?), Nó sẽ trả về 403 thay vì 404 vì vậy có thể khó gỡ lỗi.

Các vấn đề liên quan