无法在JQuery 1.6.4中使用CORS进行PUT / POST / DELETE HTTP调用

所以,我可以使用CORS成功地对我的服务进行GET调用。 但是,在POST,PUT和DELETE操作的预检级别上必须出错。 但是,根据我的判断,我的服务器响应OPTIONS查询返回的标头响应是正确的,并与之中描述的相匹配

这是我的javascript代码,在JQuery 1.6.4中使用$ .ajax。

$.ajax({ url: 'http://myhome:8080/TaskApproval/resources/tasks/2', context: this, data: '  Get carrots from the grocery storeChrisGet Carrots !!2  ', 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); } }); 

现在,这就是我的HTTP Trail的样子,由Firebug提供。

请求:

 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 

响应:

 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 

然后没有PUT(或POST或DELETE),我只是得到那个恼人的非有用的xhr对象,看起来像这样:

 readyState 0 responseText "" status 0 statusText "error" 

我很困惑,如果我在我的Ajax调用中删除了contentType,并且它为我的应用程序发送了无效的内容类型,那么浏览器实际上发送了我的PUT请求,该请求失败,因为Content-Type不是application / xml。 见下文:

 $.ajax({ url: 'http://myhome:8080/TaskApproval/resources/tasks/2', data: '  Get carrots from the grocery storeChrisGet Carrots !!2  ', 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); } }); 

导致这个HTTP Trail,再次由Firebug提供:

期权要求:

 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 

选项响应:

 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 /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 

提出回应:

 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 

415是有道理的,因为我不支持内容application / x-www-form-urlencoded,只支持application / xml。 我不明白为什么设置内容类型正确阻止PUT?

感谢您的任何见解! 我已经在网上搜索了一段时间,但找不到解决这个问题的方法。

您需要在预检和实际响应中包含CORS标头。 因此,请尝试在服务器的PUT响应中包含以下标头:

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

另外需要注意的是,CORS规范没有将’*’列为Access-Control-Allow-Headers的有效值:

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

相反,您应该尝试显式列出所有请求标头,如下所示:

 Access-Control-Allow-Headers: Content-Type 

您必须包含Content-Type,因为当Content-Type的值不是application / x-www-form-urlencoded,multipart / form-data或text / plain时,Content-Type不被视为简单标题(有关详细信息,请参阅CORS规范)在简单的标题上)。

不要忘记确保您的预选选项请求也响应:

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

使用Chrome扩展程序

要发出CORS请求,您可以使用这个简单的chrome扩展 (允许控制允许来源)

这将使您无需在headers/config添加任何额外参数即可发出CORS请求。