CORS POST请求可以从普通JavaScript中工作,但为什么不能使用jQuery呢?
我正在尝试发出一个跨源post请求,我让它在纯CORS POST请求可以从普通JavaScript中工作,但为什么不能使用jQuery呢?,javascript,jquery,xmlhttprequest,cors,Javascript,Jquery,Xmlhttprequest,Cors,我正在尝试发出一个跨源post请求,我让它在纯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.setReq
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,我的服务器用一个正确的访问控制允许源站
标题进行响应)您正在用js发送“参数”:
request.send(参数)代码>
但是jquery中的“数据”。数据定义了吗
数据:数据,
此外,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的答案在谷歌上搜索,发现您需要添加访问控制允许标题:内容类型
(下面是完整的段落)
CORS的工作原理
CORS的工作原理与Flash非常相似
基本上
浏览器将发送一个跨域的
请求服务,设置HTTP
发送请求的源文件的头文件
服务器。该服务包括
头像
访问控制允许源站访问
请说明此请求是否有效
允许
对于BOSH连接管理器,它
足以指定所有原点
通过设置
访问控制允许源站访问*
内容类型标题也必须是
白名单
访问控制允许标头
最后,对于某些类型的
请求,包括BOSH连接
管理器请求,权限
支票将被预装上
浏览器将执行选项请求和
希望返回一些HTTP头
表明哪些起源是
允许,哪些方法是允许的,
这项授权将持续多久
最后。例如,下面是
旁遮普和埃贾伯德补丁我做了
返回选项:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400
另一种可能性是,设置dataType:json
会导致JQuery发送Content-Type:application/json
头。CORS认为这是一个非标准头,需要CORS飞行前请求。因此,有几件事需要尝试:
1) 尝试配置服务器以发送正确的飞行前响应。这将以附加头的形式出现,如访问控制允许方法
和访问控制允许头
2) 删除dataType:json
设置。默认情况下,JQuery应该请求Content-Type:application/x-www-form-urlencoded
,但为了确保这一点,您可以将dataType:json
替换为contentType:'application/x-www-form-urlencoded'更新:正如TimK指出的,JQuery 1.5不需要这样做。2更多。但如果您想添加自定义标题或允许使用凭据(用户名、密码或cookie等),请继续阅读
我想我找到了答案!(4个小时后,我又骂了很多次)
您需要手动指定您将接受的所有标题(至少在FF 4.0和Chrome 10.0.648.204中是这样)
jQuery的$.ajax方法为所有跨域请求发送“x-request-with”头(我认为它是唯一的跨域请求)
因此,响应选项请求所需的缺失标头为:
//no longer needed as of jquery 1.5.2
Access-Control-Allow-Headers: x-requested-with
如果要传递任何非“简单”标题,则需要将其包含在列表中(我再发送一个):
总而言之,这里是我的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);
}
按以下方式修改Jquery:
$.ajax({
url: someurl,
contentType: 'application/json',
data: JSONObject,
headers: { 'Access-Control-Allow-Origin': '*' }, //add this line
dataType: 'json',
type: 'POST',
success: function (Data) {....}
});
Cors在请求完成之前将请求方法从POST更改为OPTIONS,因此,您的POST数据将不会被发送。
处理这个cors问题的方法是使用ajax执行请求,而ajax不支持OPTIONS方法。
示例代码:
$.ajax({
type: "POST",
crossdomain: true,
url: "http://localhost:1415/anything",
dataType: "json",
data: JSON.stringify({
anydata1: "any1",
anydata2: "any2",
}),
success: function (result) {
console.log(result)
},
error: function (xhr, status, err) {
console.error(xhr, status, err);
}
});
在c#服务器上使用此标题:
抱歉。是的。var data={action:“something”}
您可以在这里比较这两个函数的语法:我刚刚用设置中的url进行了尝试,但问题相同。ajax函数可以采用任何一种方式。我已经有两个这样的头了。我添加了另外两个。仍然“失败”“使用jQuery。简单的javascript仍然可以工作。我所能想到的最后一件事是设置jQuery.ajaxSetup({'beforeSend':function(xhr){xhr.setRequestHeader(string,string)}})
,并使用不同的发送头(这里是rails的一个示例:)谢谢这些想法。我尝试不设置数据类型,并将其设置为application/x-www-form-urlencoded
甚至text/plain
。我尝试添加了一个响应头Access Control Allow Methods“POST,GET,OPTIONS”
什么都没用。你能在JavaScript错误控制台(或Firebug的控制台)中查看请求过程中是否有错误吗?此外,如果您知道如何使用Wireshark,您可以使用它来查看实际的HTTP请求通过网络。“另一种可能是设置dataType:json会导致JQuery发送内容类型:application/json头”-这不会发生<代码>数据类型
影响接受
请求头,但不影响内容类型
请求头。请注意,jQuery 1.5.2已更改其行为。它不再添加“X-request-With”头,因此这可能不再是一个问题。(臭虫8423)@TimK,你说得对!我没有注意到他们发布了1.5.2。这就是说,如果您需要对其进行预装,此功能也可以工作。我已经更新了我的答案。所以,我很困惑。你最终还是不得不写一个中间PHP脚本?所以你不必担心使用Ajax,对吧?还是我遗漏了什么。没有JavaScript唯一的解决方案吗?@Elisabeth此方法仅在您控制请求的目标时有效……它不是中间脚本。它是我们请求的位置的PHP的顶部。这更有意义吗?是的
$.ajax({
url: someurl,
contentType: 'application/json',
data: JSONObject,
headers: { 'Access-Control-Allow-Origin': '*' }, //add this line
dataType: 'json',
type: 'POST',
success: function (Data) {....}
});
$.ajax({
type: "POST",
crossdomain: true,
url: "http://localhost:1415/anything",
dataType: "json",
data: JSON.stringify({
anydata1: "any1",
anydata2: "any2",
}),
success: function (result) {
console.log(result)
},
error: function (xhr, status, err) {
console.error(xhr, status, err);
}
});
if (request.HttpMethod == "OPTIONS")
{
response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");
response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
response.AddHeader("Access-Control-Max-Age", "1728000");
}
response.AppendHeader("Access-Control-Allow-Origin", "*");