一个CORS POST请求从普通的javascript工作,但为什么不用jQuery?

我正在尝试创建一个Cross Origin发布请求,并且我使用如下简单的Javascript工作:

var request = new XMLHttpRequest();
var params = "action=something";
request.open('POST', url, true);
request.onreadystatechange = function() {if (request.readyState==4) alert("It worked!");};
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.setRequestHeader("Content-length", params.length);
request.setRequestHeader("Connection", "close");
request.send(params);

但我想使用jQuery,但我无法实现它的工作。 这就是我想要的:

$.ajax(url, {
    type:"POST",
    dataType:"json",
    data:{action:"something"}, 
    success:function(data, textStatus, jqXHR) {alert("success");},
    error: function(jqXHR, textStatus, errorThrown) {alert("failure");}
});

这导致失败。 如果有人知道为什么jQuery不起作用,请让我们都知道。 谢谢。

(我使用jQuery 1.5.1和Firefox 4.0,并且我的服务器正在响应正确的Access-Control-Allow-Origin标头)


更新:正如TimK指出的,这不再需要jQuery 1.5.2。 但是,如果您想添加自定义标题或允许使用凭据(用户名,密码或cookie等),请继续阅读。


我想我找到了答案! (4小时后又有很多咒骂)

//This does not work!!
Access-Control-Allow-Headers: *

你需要手动指定你将接受的所有头文件(至少FF 4.0和Chrome 10.0.648.204中是这种情况)。

jQuery的$ .ajax方法为所有跨域请求发送“x-requested-with”标头(我认为它是唯一的跨域)。

因此,对OPTIONS请求做出响应的缺失头部是:

//no longer needed as of jquery 1.5.2
Access-Control-Allow-Headers: x-requested-with

如果你传递任何非简单的标题,你需要将它们包含在你的列表中(我发送一个):

//only need part of this for my custom header
Access-Control-Allow-Headers: x-requested-with, x-requested-by

所以把它放在一起,这里是我的PHP:

// * wont work in FF w/ Allow-Credentials
//if you dont need Allow-Credentials, * seems to work
header('Access-Control-Allow-Origin: http://www.example.com');
//if you need cookies or login etc
header('Access-Control-Allow-Credentials: true');
if ($this->getRequestMethod() == 'OPTIONS')
{
  header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
  header('Access-Control-Max-Age: 604800');
  //if you need special headers
  header('Access-Control-Allow-Headers: x-requested-with');
  exit(0);
}

另一种可能是设置dataType: json会导致JQuery发送Content-Type: application/json头。 这被CORS视为非标准标题,并且需要CORS预检请求。 所以有几件事要尝试:

1)尝试配置您的服务器以发送适当的预检响应。 这将以Access-Control-Allow-MethodsAccess-Control-Allow-Headers标题等附加标题的形式出现。

2)删除dataType: json设置。 JQuery应该默认请求Content-Type: application/x-www-form-urlencoded ,但可以肯定的是,你可以用contentType: 'application/x-www-form-urlencoded'替换dataType: json contentType: 'application/x-www-form-urlencoded'


你在js中发送“params”: request.send(params);

但“jquery中的数据”。是否定义了data:data, ?: data:data,

此外,您在网址中发生错误:

$.ajax( {url:url,
         type:"POST",
         dataType:"json",
         data:data, 
         success:function(data, textStatus, jqXHR) {alert("success");},
         error: function(jqXHR, textStatus, errorThrown) {alert("failure");}
});

您将语法与$ .post的语法混合在一起


更新 :我基于monsur的回答进行搜索,我发现你需要添加Access-Control-Allow-Headers: Content-Type (下面是完整的段落)

http://metajack.im/2010/01/19/crossdomain-ajax-for-xmpp-http-binding-made-easy/

CORS如何工作

CORS的工作方式与Flash的crossdomain.xml文件非常相似。 基本上,浏览器会向服务发送一个跨域请求,将HTTP标头Origin设置为请求服务器。 该服务包含一些标题,如Access-Control-Allow-Origin,以指示是否允许这样的请求。

对于BOSH连接管理器,通过将Access-Control-Allow-Origin的值设置为*可以指定允许所有源。 Content-Type头还必须在Access-Control-Allow-Headers标题中列出白名单。

最后,对于某些类型的请求,包括BOSH连接管理器请求,权限检查将会预先进行。 浏览器将执行一个OPTIONS请求,并期望返回一些HTTP标头,这些标头指示允许哪些来源,允许哪些方法以及此授权将持续多久。 例如,以下是我为OPTIONS返回的旁遮普和ejabberd补丁:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type 
Access-Control-Max-Age: 86400
链接地址: http://www.djcxy.com/p/42441.html

上一篇: A CORS POST request works from plain javascript, but why not with jQuery?

下一篇: How to delete temp folder data using python script