2011-09-28 48 views
12

因此,我可以使用CORS成功地对我的服务进行GET调用。但是,在POST,PUT和DELETE操作的预检级别上必须出错。然而,从我可以告诉,我的服务器的响应返回响应的OPTIONS查询是正确的,并与无法使用JQuery 1.6.4中的CORS进行PUT/POST/DELETE HTTP调用

中描述的匹配这里是我的JavaScript代码,在JQuery 1.6.4中使用$ .ajax。

$.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); 
    } 
}); 

现在,这是我的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: '<?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); 
    } 
}); 

导致这个HTTP径,再次萤火虫的礼貌:

OPTIONS请求:

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请求:

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窗体-urlencoded,唯一的应用程序/ XML。我不明白的是为什么设置Content-Type能够正确地阻止PUT?

感谢您的任何见解!我一直在搜索互联网很长一段时间,并且找不到解决这个问题的办法。

回答

30

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

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

另一个要注意的是,CORS规范并未列出“*”作为访问控制允许报头的有效值:

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

相反,你应该尽量明确列出所有的请求头,像这样:

Access-Control-Allow-Headers: Content-Type 

您必须包括的内容,泰因为当Content-Type的值不是application/x-www-form-urlencoded,multipart/form-data或text/plain(请参阅CORS规范以获取有关简单头文件的更多详细信息)时,Content-Type不被视为简单头文件。

+0

@ monsur--那确实解决了它!谢谢。我曾尝试在所有响应中包含标题,但仍然存在错误 - 因为我不理解Content-Type的限制。谢谢你的澄清! – ChrisBean

-1

不要忘记,以确保您的打架前的选项的要求也回应说:

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

使用Chrome扩展

为了CORS请求时,你可以使用这个简单的chrome extension(允许控制允许来源)

这会让你在headers/config没有增加任何额外的参数CORS请求。