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

Posted

技术标签:

【中文标题】无法在 JQuery 1.6.4 中使用 CORS 进行 PUT/POST/DELETE HTTP 调用【英文标题】:Unable to make PUT/POST/DELETE HTTP Call using CORS in JQuery 1.6.4 【发布时间】:2011-11-27 02:50:49 【问题描述】:

因此,我可以使用 CORS 成功地对我的服务进行 GET 调用。但是,POST、PUT 和 DELETE 操作的预检级别肯定有问题。但是,据我所知,我的服务器响应 OPTIONS 查询返回的标头响应是正确的,并且与

中描述的匹配

这是我的 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 跟踪,再次由 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。我不明白为什么正确设置 Content-Type 会阻止 PUT?

感谢您的任何见解!我已经在互联网上搜索了很长时间,但找不到解决此问题的方法。

【问题讨论】:

【参考方案1】:

不要忘记确保您的预检选项请求也回复了:

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

【讨论】:

【参考方案2】:

您需要在预检和实际响应中都包含 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(请参阅 CORS 规范有关简单标题的更多详细信息)。

【讨论】:

@monsur——这确实解决了它!谢谢你。我确实尝试在所有响应中包含标题,但仍然有错误——因为我不了解对 Content-Type 的限制。感谢您的澄清!

以上是关于无法在 JQuery 1.6.4 中使用 CORS 进行 PUT/POST/DELETE HTTP 调用的主要内容,如果未能解决你的问题,请参考以下文章

CORS问题无法解析jquery,laravel 5.2

带有域字段的 CORS cookie 仅在使用 jQuery AJAX 的 Firefox 中设置

尽管有 web.config 条目,但带有 ASP.NET WCF 服务的 jQuery AJAX CORS 无法正常工作

Jquery Ajax CORS + HttpOnly Cookie

使用 jQuery Ajax 和 PHP 的 CORS 请求

使用 $.support.cors = true 是不是安全?在 jQuery 中?