2015-01-16 16 views
5

Sto provando a scrivere una richiesta AJAX molto semplice in Django, e continuo a ricevere l'errore 403 vietato sia nelle console Chrome Dev che in quelle Django. Ho postato una domanda simile l'altro giorno e ho provato tutte le soluzioni proposte incluso @csrf_exempt (per escludere se si tratta anche di un problema csrf), ho provato a includere csrfmiddlewaretoken: '{{csrf_token}}' nella richiesta POST AJAX (sotto i dati), anche questo non risolve il problema. Ecco il mio codice.Perché ricevo un errore Proibito 403 quando si utilizza @csrf_exempt nella richiesta 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/') 

E il codice AJAX nel modello:

<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), 

cose degne di nota: il middleware

  1. ho CSRF attivata nelle mie impostazioni

  2. all'interno del codice jQuery AJAX, URL e i dati sono entrambi inviare le informazioni corrette

  3. quando clicco sul pulsante Elimina, ottengo l'errore proibito 403.

  4. La stampa "richiesta è ajax" non viene stampata nella console (o in qualsiasi luogo).

Sono anche confuso perché sto ottenendo informazioni contrastanti. Mi è stato detto che dovrei aggiungere il valore csrf tramite javascript (https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/). Questo mi lascia con 2 domande. 1. Qual è la differenza rispetto all'aggiunta di csrfmiddlewaretoken: '{{csrf_token}}' nella mia richiesta POST? e 2. Ancora più importante, il fatto che ottenga ancora un errore 403 quando utilizzo il tipo @csrf_exempt rende questo un punto controverso?

+0

Ma non si invia il token csrf nella richiesta. –

+0

L'aggiunta del decoratore csrf_exempt dovrebbe rimuovere tale restrizione, ma è strano che venga restituito un 403. – Brandon

+0

Su una nota diversa, il codice JavaScript non sarà in grado di elaborare "HttpResponseRedirect" lato server.Dovresti passarlo come una stringa e poi fare: 'top.location = json.redirect_url' per esempio. – Brandon

risposta

0

Per la mia comprensione, delete_object è una funzione all'interno profile_listview, ma il profile_listview non ha chiamato esso. Pertanto, profile_listview non ha risposta http. Invia il messaggio di errore

+0

Ho finito per spostare il modulo di roba AJAX delete_object in profile_listview. Quindi mi sono appena sbarazzato della funzione delete_object e l'ho inserita in un'unica funzione. – stephan

0

come catavaran penso che hai chiamato vista errata. Dovresti chiamare la vista delete_object. Ad esempio, aggiungere URL

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

E AJAX

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

Mi auguro che aiuta

+0

Ha senso, ma delete_object è attualmente il metodo profile_listview INSIDE, quindi dovrebbe funzionare correttamente? O no. – stephan

+0

Penso che dovrebbe funzionare con qualche tipo di vista generica. Ma non è una visione generica corretta. Non riesco a capire come il tuo Django gestisca la funzione delete_object. Se questo dovrebbe funzionare puoi fornire un articolo in cui descrivere questo modo di creare viste – dyus

1

Il @csrf_exempt deve essere prima della funzione chiamata da urls.py. Nell'esempio dell'OP, delete_object non è mai stato chiamato perché l'errore si verificava già quando chiamava profile_listview che non aveva il decoratore.

Su una nota a margine, si può avere una situazione simile (utilizzando @csrf_exempt ma ottenendo 403) se l'URL non esiste. Per qualche ragione (sicurezza?), Restituirà un 403 piuttosto che un 404, quindi può essere difficile eseguire il debug.

Problemi correlati