一个CORS POST请求从普通的javascript工作,但为什么不与jQuery?
我正在尝试创build一个“跨源”发布请求,并且我使用如下简单的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等),请继续阅读。
我想我find了答案! (4小时后又诅咒了很多)
//This does not work!! Access-Control-Allow-Headers: *
您需要手动指定您将接受的所有标题(至lessFF 4.0和Chrome 10.0.648.204中是这种情况)。
jQuery的$ .ajax方法为所有跨域请求发送“x-requested-with”头(我认为它是唯一的跨域)。
因此,对OPTIONS请求做出响应的缺less头部是:
//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)尝试configuration您的服务器发送适当的预检响应。 这将以附加标题的forms出现,比如Access-Control-Allow-Methods
和Access-Control-Allow-Headers
。
2)删除dataType: json
设置。 JQuery应该默认请求Content-Type: application/x-www-form-urlencoded
,但是可以确定的是,你可以用contentType: 'application/x-www-form-urlencoded'
replacedataType: json
contentType: 'application/x-www-form-urlencoded'
你在js中发送“params”: request.send(params);
但“jquery中的数据”。是数据定义?: data:data,
另外,您在url中有错误:
$.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的回答search,我发现你需要添加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连接pipe理器,通过将Access-Control-Allow-Origin的值设置为*,可以指定允许所有的源。 Content-Type头还必须在Access-Control-Allow-Headers头中被列入白名单。
最后,对于某些types的请求(包括BOSH连接pipe理器请求),权限检查将被预先考虑。 浏览器将执行OPTIONS请求,并期望获得一些HTTP标头,指明允许哪些来源,允许哪些方法以及授权持续多久。 例如,下面是我所做的旁遮普语和ejabberd补丁返回的选项:
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: Content-Type Access-Control-Max-Age: 86400
- 请求标题字段Access-Control-Allow-Headers在预检响应中本身不允许
- 在Chrome 48和49中禁用networking安全
- chrome中的错误:Content-Type不被Access-Control-Allow-Headers所允许
- 什么是阻止恶意代码欺骗“Origin”头来利用CORS?
- Firefox CORS请求给予“跨源请求被阻止”,尽pipe标题
- 如何正确使用AngularJS中的HTTP.GET? 具体而言,对于外部API调用?
- 确定由于不安全的响应或连接拒绝而导致ajax呼叫失败
- 那么,JSONP还是CORS?
- xmlHttp.getResponseHeader +不适用于CORS