2011-09-28 10 views
12

Quindi, posso effettuare correttamente una chiamata GET al mio servizio utilizzando CORS. Tuttavia, qualcosa deve andare storto a livello di preflight per le operazioni POST, PUT e DELETE. Tuttavia, da quello che posso dire, le risposte dell'intestazione che il mio server sta restituendo in risposta alla query OPTIONS sono corrette e corrispondono a quelle descritte inImpossibile eseguire la chiamata HTTP PUT/POST/DELETE utilizzando CORS in JQuery 1.6.4

Ecco il mio codice javascript, utilizzando $ .ajax in JQuery 1.6.4.

$.ajax({ 
    url: 'http://myhome:8080/TaskApproval/resources/tasks/2', 
    context: this, 
    data: '<?xml version="1.0" encoding="UTF-8"?> <task> <description>Get carrots from the grocery store</description><originator>Chris</originator><subject>Get Carrots !!</subject><taskId>2</taskId> </task> ', 
    timeout: 30000, 
    type: 'PUT', 
    contentType: 'application/xml', 
    success: function(response) { 
    alert(response); 
    result = response; 
    }, 
    error: function(xhr) { 
    alert('Error! Status = ' + xhr.status + " Message = " + xhr.statusText); 
    } 
}); 

Ora, questo è come appare il mio HTTP Trail, per gentile concessione di Firebug.

Richiesta:

OPTIONS /TaskApproval/resources/tasks/2 HTTP/1.1 
Host: widgethome:8080 
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-us,en;q=0.5 
Accept-Encoding: gzip, deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Connection: keep-alive 
Origin: http://localhost:8080 
Access-Control-Request-Method: PUT 
Access-Control-Request-Headers: content-type 

Risposta:

HTTP/1.1 200 OK 
X-Powered-By: Servlet/3.0 
Server: GlassFish v3 
Allow: OPTIONS,GET,DELETE,HEAD,PUT, POST 
Access-Control-Allow-Origin: * 
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE 
Access-Control-Max-Age: 1000 
Access-Control-Allow-Headers: * 
Content-Type: application/xml 
Content-Length: 2792 
Date: Wed, 28 Sep 2011 18:21:11 GMT 

Non esiste quindi un PUT (o POST o DELETE), ottengo solo che oggetto XHR non sia fastidioso che assomiglia a questo:

readyState 0 
responseText "" 
status 0 
statusText "error" 

Sono molto confuso che se quindi rimuovere il contentType nella mia chiamata Ajax, e invia un invalid tipo di contenuto per la mia applicazione, il browser invia effettivamente la mia richiesta PUT, che fallisce perché Content-Type non è application/xml. Vedere di seguito:

$.ajax({ 
    url: 'http://myhome:8080/TaskApproval/resources/tasks/2', 
    data: '<?xml version="1.0" encoding="UTF-8"?> <task> <description>Get carrots from the grocery store</description><originator>Chris</originator><subject>Get Carrots !!</subject><taskId>2</taskId> </task> ', 
    timeout: 30000, 
    type: 'PUT', 
    //contentType: 'application/xml', 
    success: function(response) { 
    alert(response); 
    result = response; 
    }, 
    error: function(xhr) { 
    alert('Error! Status = ' + xhr.status + " Message = " + xhr.statusText); 
    } 
}); 

conduce a questa Trail HTTP, ancora una volta per gentile concessione di Firebug:

Opzioni Richiesta:

OPTIONS /TaskApproval/resources/tasks/2 HTTP/1.1 
Host: myhome:8080 
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-us,en;q=0.5 
Accept-Encoding: gzip, deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Connection: keep-alive 
Origin: http://localhost:8080 
Access-Control-Request-Method: PUT 

opzioni di risposta:

HTTP/1.1 200 OK 
X-Powered-By: Servlet/3.0 
Server: GlassFish v3 
Allow: OPTIONS,GET,DELETE,HEAD,PUT, POST 
Access-Control-Allow-Origin: * 
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE 
Access-Control-Max-Age: 1000 
Access-Control-Allow-Headers: * 
Content-Type: application/xml 
Content-Length: 2792 
Date: Wed, 28 Sep 2011 18:26:23 GMT 

Put Richiesta:

PUT /TaskApproval/resources/tasks/2 HTTP/1.1 
Host: myhome:8080 
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2 
Accept: */* 
Accept-Language: en-us,en;q=0.5 
Accept-Encoding: gzip, deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Connection: keep-alive 
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
Referer: http://localhost:8080/TaskApproval/crossdomain.html 
Content-Length: 197 
Origin: http://localhost:8080 

Risposta Put:

HTTP/1.1 415 Unsupported Media Type 
X-Powered-By: Servlet/3.0 
Server: GlassFish v3 
Content-Type: text/html 
Content-Length: 1069 
Date: Wed, 28 Sep 2011 18:26:23 GMT 

Il 415 ha un senso perché non condivido il contenuto application/x-www-form-urlencoded, solo application/xml. Quello che non capisco è perché l'impostazione del Content-Type impedisce correttamente il PUT?

Grazie per qualsiasi intuizione! Ho cercato su Internet per un po 'di tempo, e non riesco a trovare una soluzione per questo problema.

risposta

30

È necessario includere le intestazioni CORS sia nella verifica preliminare che nella risposta effettiva.Quindi, cercare tra cui le seguenti intestazioni nella risposta PUT dal server:

Access-Control-Allow-Origin: * 
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE 
Access-Control-Allow-Headers: Content-Type 

Un'altra cosa da notare è che la specifica CORS non elenca '*' come un valore valido per Access-Control-Allow-intestazioni:

http://www.w3.org/TR/cors/#access-control-allow-headers-response-he

Invece, si dovrebbe cercare in modo esplicito elenco di tutte le intestazioni di richiesta in questo modo:

Access-Control-Allow-Headers: Content-Type 

è necessario includere Content-Ty pe perché Content-Type non è considerato un'intestazione semplice quando il suo valore non è application/x-www-form-urlencoded, multipart/form-data o text/plain (vedi le specifiche CORS per maggiori dettagli sulle intestazioni semplici).

+0

@ monsur-- che ha risolto! Grazie. Ho provato a includere le intestazioni in tutte le risposte, ma ho continuato ad avere errori - perché non ho capito la restrizione su Content-Type. Grazie per il chiarimento! – ChrisBean

-1

Non dimenticare di assicurarsi che la vostra richiesta Opzioni Prefight anche risposto con:

Access-Control-Allow-Origin: * 
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE 
Access-Control-Allow-Headers: Content-Type 
0

Utilizzando Chrome Extension

Per rendere CORS richiesta, è possibile utilizzare questo semplice controllo chrome extension(Permetti Consentire l'origine).

Ciò consente di effettuare la richiesta CORS senza aggiungere alcun parametro aggiuntivo in headers/config.