2011-08-22 7 views
8
curl --dump-header - -H "Content-Type: application/json" -X POST --data '{"latlong": "test"}' http://localhost:8000/geo/api/geolocation/ 

Quanto sopra funziona bene ma quando provo a replicare il POST nell'ajax in basso ottengo 500 errori.Ajax POST e Django Tastypie

$.ajax({ 
    type: 'POST', 
    url: 'http://localhost:8000/geo/api/geolocation/', 
    data: '{"latlong": "test"}', 
    success: latlongSaved(), 
    dataType: "application/json", 
    processData: false, 
}); 

messaggio di errore è:

{"error_message": "The format indicated 'application/x-www-form-urlencoded' had no available deserialization method. Please check your ``formats`` and ``content_types`` on your Serializer." .... } 

Degno di nota questo è di dominio croce e sto usando il django-crossdomainxhr-middleware.py trovato tramite git: Gist

Se posso aggiungere un tipo di contenuto per la chiamata AJAX in questo modo:

contentType: "application/json" 

ottengo questo errore di nuovo:

XMLHttpRequest cannot load http://localhost:8000/geo/api/geolocation/. Request header field Content-Type is not allowed by Access-Control-Allow-Headers. 
Request URL:http://localhost:8000/geo/api/geolocation/ 
Request Method:OPTIONS 
Status Code:200 OK 
Request Headersview source 
Access-Control-Request-Headers:Origin, Content-Type, Accept 
Access-Control-Request-Method:POST 
Origin:http://localhost:3000 
Response Headersview source 
Access-Control-Allow-Methods:POST,GET,OPTIONS,PUT,DELETE 
Access-Control-Allow-Origin:* 
Content-Type:text/html; charset=utf-8 
Date:Tue, 23 Aug 2011 07:59:49 GMT 
Server:WSGIServer/0.1 Python/2.6.1 
+0

Controllare i documenti: potrebbe essere necessario impostare l'opzione JSON nella stringa dell'URL. – Marcin

+0

Puoi pubblicare il diff tra le intestazioni di richiesta 'curl' e le intestazioni jQuery? Puoi vedere le intestazioni jQuery nella scheda della console all'interno di Firebug. –

risposta

7

si dichiara in modo esplicito il tipo di contenuto nella chiamata a curl, ma non vengono specifico sul jQuery.ajax() chiamata.

Aggiornare il tuo JavaScript per definire esattamente ciò che il tipo di contenuto sarà:

$.ajax({ 
    type: 'POST', 
    url: 'http://localhost:8000/geo/api/geolocation/', 
    data: '{"latlong": "test"}', 
    success: latlongSaved(), 
    dataType: "application/json", 
    processData: false, 
    contentType: "application/json" 
}); 
+0

Solo per chiarezza potresti dire cosa fa "dataType"? –

+0

Già provato, messaggio di errore aggiunto sopra. –

+0

Stai facendo chiamate AJAX su più domini. Questo non funzionerà con JSON, devi usare JSONP – Eduardo

3

Aggiungere XsSharing (https://gist.github.com/1164697) per settings.py:

MIDDLEWARE_CLASSES = [ 
    ..., 
    'django-crossdomainxhr-middleware.XsSharing' 
] 

quindi utilizzare il seguente JavaScript per effettuare una chiamata AJAX:

$.ajax({ 
    type: 'POST', 
    url: 'http://localhost:8000/geo/api/geolocation/', 
    data: '{"latlong": "test"}', 
    success: latlongSaved(), 
    contentType:'application/json', 
    dataType: 'application/json', 
    processData: false, 
}); 

Si noti che data deve essere una stringa JSON ben formata, altrimenti jQuery ignorerà silenziosamente la chiamata ajax e non farà nulla.

Cosa c'è dietro le quinte è che la chiamata ajax invierà prima OPTIONS /geo/api/geolocation/. Poiché l'intestazione della risposta viene modificata dal middleware XsSharing, jQuery emetterà un'altra richiesta POST /geo/api/geolocation che esegue la creazione effettiva.

+0

Questo: "Si noti che i dati devono essere una stringa JSON ben formata, altrimenti jQuery ignorerà silenziosamente la chiamata ajax e non farà nulla", mi ha aiutato molto! Grazie –