2016-02-07 17 views
5

Ho un semplice server tornado che ha la classe:server di Tornado: abilitare CORS richieste

class BaseHandler(tornado.web.RequestHandler): 
    def set_default_headers(self): 
     print "setting headers!!!" 
     self.set_header("Access-Control-Allow-Origin", "*") 

Quando un regolare (senza CORS) richiesta è fatta, le risposte server come previsto, tra l'Access-Control- Intestazione Allow-Origin. Ma quando faccio una richiesta di posta proveniente da domini diversi (usando), la risposta è 404 e viene visualizzato un errore: "XMLHttpRequest non può caricare http://dev-machine:8090/handshake. Nessuna intestazione 'Access-Control-Allow-Origin' è presente sulla risorsa richiesta. L'origine 'http://localhost:8090' non è quindi consentita l'accesso.La risposta aveva codice di stato HTTP 404. "

Puoi dire se mi manca qualcosa? (un'altra intestazione/altra configurazione/altro)

+0

che' pass' v'è superfluo/sbagliato –

risposta

21

Il codice manca preflight, la richiesta OPTIONS.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS:

Le opere canoniche delle risorse di condivisione Cross-Origin aggiungendo nuovi HTTP intestazioni che consentono ai server di descrivere l'insieme delle origini che sono permesso di leggere le informazioni utilizzando un browser web. Inoltre, per i metodi di richiesta HTTP che possono causare effetti collaterali sui dati utente (nel metodo , per i metodi HTTP diversi da GET o per l'utilizzo POST con determinati tipi MIME), la specifica impone che i browser "preflight" la richiesta , sollecitando i metodi supportati dal server con un metodo di richiesta HTTP OPTIONS e quindi, dopo "approvazione" dal server , inviando la richiesta effettiva con il metodo effettivo HTTP . I server possono anche notificare ai clienti se le "credenziali" (inclusi cookie e dati di autenticazione HTTP) devono essere inviate con le richieste .

Per implementare il gestore di verifica preliminare è sufficiente aggiungere il gestore di opzioni con le stesse intestazioni e nessun corpo.

class BaseHandler(tornado.web.RequestHandler): 

    def set_default_headers(self): 
     print "setting headers!!!" 
     self.set_header("Access-Control-Allow-Origin", "*") 
     self.set_header("Access-Control-Allow-Headers", "x-requested-with") 
     self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS') 

    def post(self): 
     self.write('some post') 

    def get(self): 
     self.write('some get') 

    def options(self): 
     # no body 
     self.set_status(204) 
     self.finish() 

modificare

Ho aggiunto x-requested-with intestazione permesso lista. E qui è semplice campione jquery:

$.ajax({ 
    url: "http://some_tornado/api", 
    type: "POST", 
    crossDomain: true, 
    data: 'some_data', 
    success: function (response) { 
    alert(response); 
    }, 
    error: function (xhr, status) { 
    alert("error"); 
    } 
}); 

E alcuni veramente buono articolo su cors - http://dev.housetrip.com/2014/04/17/unleash-your-ajax-requests-with-cors/

+0

cosa significa dovrei cambiare il mio post JS e creare. una richiesta di "opzioni" – benams

+1

Ho aggiunto degli esempi, in pratica il preflight è fatto dal browser sotto il cofano – kwarunek

+0

Sì, l'ho trovato dopo aver postato questo commento Grazie, è stato davvero d'aiuto! – benams

4

La risposta da kwarunek mi ha portato a una soluzione per il mio problema con il PUT e la richiesta di eliminazione. L'unica cosa è che la soluzione è troppo appropriata per l'esempio con GET e POST. In questo caso la linea

self.set_header("Access-Control-Allow-Origin", "*") 

è in realtà sufficiente (se il browser non blocca CORS prima di tutto). È però più rilevante per le richieste PUT e DELETE. Quello che succede qui a livello di rete può essere leggermente più complesso rispetto al caso GET/POST.

"Se la richiesta è una richiesta" non semplice ", il browser invia prima una richiesta OPZIONI di preflight senza dati, per verificare che il server accetterà la richiesta. Verbo HTTP diverso da GET o POST (es. PUT, DELETE)."cf. non-simple requests

class BaseHandler(tornado.web.RequestHandler): 

    def set_default_headers(self): 
     print("setting headers!!!") 
     self.set_header("Access-Control-Allow-Origin", "*") 
     self.set_header("Access-Control-Allow-Headers", "x-requested-with") 
     self.set_header('Access-Control-Allow-Methods', ' PUT, DELETE, OPTIONS') 

    def options(self): 
     # no body 
     self.set_status(204) 
     self.finish() 

Ora tutti i gestori che ereditano da BaseHandler sono completamente CORS-grado:

class MyHandler(BaseHandler): 

    def put(self): 
     self.write('some post') 

    def delete(self): 
     self.write('some get') 
Problemi correlati