Unable to make PUT/POST/DELETE HTTP Call using CORS in JQuery 1.6.4
So, I can successfully make a GET call to my service using CORS. However, something must be going wrong at the preflight level for the POST, PUT, and DELETE operations. However, from what I can tell, the header responses my server is returning in response to the OPTIONS query are correct and match those described in
Here is my javascript code, using $.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);
}
});
Now, this is what my HTTP Trail looks like, courtesy of Firebug.
Request:
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
Response:
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
There is then no PUT (or POST or DELETE), I just get that annoying non-helpful xhr object that looks like this:
readyState 0
responseText ""
status 0
statusText "error"
I'm very mystified that if I then remove the contentType in my Ajax call, and it sends an invalid content type per my application, the browser actually sends my PUT request, which fails because the Content-Type is not application/xml. See below:
$.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);
}
});
Leads to this HTTP Trail, again courtesy of Firebug:
Options Request:
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
Options Response:
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 Request:
PUT /TaskApproval/reso开发者_开发百科urces/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
Put Response:
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
The 415 makes sense because I don't support content application/x-www-form-urlencoded, only application/xml. What I don't understand is why does setting the Content-Type correctly prevent the PUT?
Thanks for any insight! I've been searching the internet for quite some time, and can't find a solution for this problem.
You need to include CORS headers in both the preflight and the actual response. So try including the following headers in the PUT response from your server:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Headers: Content-Type
One other thing to note is that the CORS spec does not list '*' as a valid value for Access-Control-Allow-Headers:
http://www.w3.org/TR/cors/#access-control-allow-headers-response-he
Instead, you should try explicitly listing all the request headers like so:
Access-Control-Allow-Headers: Content-Type
You must include Content-Type because the Content-Type is not considered a simple header when its value is not application/x-www-form-urlencoded, multipart/form-data, or text/plain (See the CORS spec for more details on simple headers).
Don't forget to make sure your prefight Options request also responded with:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Headers: Content-Type
精彩评论