2012-03-08 6 views
5

Sto tentando di impostare la condivisione di risorse Cross-Origin semplice utilizzando javery (1.7.1) ajax sul client e server python (django) apache. Secondo tutte le istruzioni che ho letto i miei intestazioni siano impostate correttamente, ma io continuo a ricevere il seguente errore:CORS Access-Control-Allow-Origin nonostante le intestazioni corrette

XMLHttpRequest cannot load http://myexternaldomain.com/get_data . Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.

L'intestazione essendo che sto cercando di (io non sono sicuro che è anche sempre passato il browser) invia è:

Request URL:http://myexternaldomain.com/get_data 
Accept:application/json, text/javascript, */*; q=0.01 
Origin:http://localhost:8080 
Referer:http://localhost:8080/static/js/test-zetta.html 
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11 

Il codice JavaScript viene

var request = $.ajax({ 
     url : "http://myexternaldomain.com/get_data", 
     type : "POST", 
     dataType : "json", 
     crossDomain : true 
    }); 

noti che origin è impostato correttamente. Il server aggiunge l'intestazione Access-Control-Allow-Origin = * utilizzando il seguente codice python

def process_response(self, response): 
    if response.has_header('Access-Control-Allow-Origin'): 
      return response 

    response['Access-Control-Allow-Origin'] = '*' 
    return response 

def get_orders(request): 
    """ Tell worker what to do """ 
    response_data = {} 
    response_data['action'] = 'probe' 
    response = process_response(HttpResponse(json.dumps(response_data), mimetype="application/json")) 
    return response 

Se visito direttamente l'indirizzo, sembra confermare che l'intestazione è impostato correttamente

Access-Control-Allow-Origin:* 
Content-Type:application/json 
Date:Thu, 08 Mar 2012 05:06:25 GMT 
Server:Apache/2.2.20 (Ubuntu) 
Transfer-Encoding:chunked 

Tuttavia nel dominio croce impostazione fallisce sempre (ho provato sia Chrome che Firefox). Ho provato l'attuazione del codice esattamente come per la risposta selezionata per this domanda, ma ottengo lo stesso errore

Aggiornamento

Sono abbastanza sicuro che il problema sia lato server, come ho già riuscito ad ottenere le mie chiamate ajax funzionano con un diverso server pubblico CORS abilitato. Quando paragono le intestazioni provenienti da questo server pubblico e quelle restituite dalla mia (quando provo dallo stesso dominio), non riesco a vedere nessuna differenza importante che possa spiegare la differenza (vedi sotto).

Una sottigliezza che ho escluso, che può o potrebbe essere importante è che il dominio effettivo è un dominio amazon di più sottodomini. L'indirizzo reale è http://ec2-23-20-27-108.compute-1.amazonaws.com/get_orders, sentiti libero di verificarlo per vedere cosa sto facendo male.

Dal server pubblico

Access-Control-Allow-Origin:* 
Connection:Keep-Alive 
Content-Encoding:gzip 
Content-Length:622 
Content-Type:text/html 
Date:Thu, 08 Mar 2012 15:33:20 GMT 
Keep-Alive:timeout=15, max=99 
Server:Apache/2.2.14 (Ubuntu) 
Vary:Accept-Encoding 
X-Powered-By:Perl/5.8.7, PHP/4.4.0 

dal mio server - (non funzionante dominio croce)

Access-Control-Allow-Origin:* 
Content-Encoding:gzip 
Content-Type:text/plain 
Date:Thu, 08 Mar 2012 15:32:24 GMT 
Server:Apache/2.2.20 (Ubuntu) 
Transfer-Encoding:chunked 
Vary:Accept-Encoding 
+1

In passato ho provato a abilitare CORS per i dati Json e non ha mai avuto successo. CORS può essere traballante come quello. Faresti molto meglio a tornare JSON-P. – xbonez

+0

Stai solo pubblicando le intestazioni dallo scambio _final_ tra il tuo server remoto e il client locale. Se osservi lo scambio completo, sono sicuro che vedrai una richiesta OPTIONS insieme a una risposta che contiene le intestazioni Access-Control-Allow-Methods e Access-Control-Allow-Headers. –

risposta

5

Quindi ero indotto in errore dalla risposta dall'URL, e in effetti il ​​problema era che quando facevo la richiesta Ajax, stavo ottenendo un 403 (rivelato solo in firefox non chrome) errore dovuto alla protezione csrf.

+1

Oh uomo, grazie mille. Ho avuto il mio wrapper 'enable_cors' attorno al mio wrapper' csrf_exemp', necessario per invertire. Ero tipo, WTF ... – orokusaki

5

Bisogna implementare un "pre-flighted" richiesta e risposta perché la vostra la situazione conta come una richiesta "not so simple". I CORS di base, che richiedono solo l'intestazione Origin, possono avere solo tipi di contenuto "application/x-www-form-urlencoded", "multipart/form-data" e "text/plain". Poiché si restituisce "application/json", non si soddisfa questo requisito.

Non so nulla di Django, ma ho trovato più facile implementare il supporto CORS al di fuori della mia applicazione attraverso l'uso di uno Tomcat filter. Sembra che tu possa do the same thing con Django.

2013-08-11: Sembra che il repository GitHub non ci sia più.Ma il pacchetto Django sembra essere ancora disponibile al https://pypi.python.org/pypi/django-cors/0.1

+0

Abbastanza sicuro che il browser debba occuparsi della richiesta di preflight .... almeno Chrome lo fa. –

+0

Ma il server deve riconoscerlo. Il suo script risponde solo alle richieste di base aggiungendo l'intestazione Origin ad ogni richiesta. –

+0

Ho provato a rendere semplice la richiesta, rendendo i miei dati una stringa semplice, aspettando il testo normale nella chiamata $ .ajax e restituendo mimetype = 'text/plain' nel python, ma otteniamo comunque gli stessi errori. – zenna

2

Stavo usando l'eccellente libreria django-cors-headers e ho riscontrato anche questo problema. Per me, la soluzione era aggiungere 'accept-encoding' alla tupla CORS_ALLOW_HEADERS di default.

Problemi correlati