CORS POST请求可以使用普通的javascript,但为什么不使用jQuery?

时间:2011-04-07 17:12:01

标签: javascript jquery xmlhttprequest cors

我正在尝试发布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标头进行响应)

5 个答案:

答案 0 :(得分:66)

更新:正如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);
}

答案 1 :(得分:15)

另一种可能性是设置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,但为了确保您可以将dataType: json替换为contentType: 'application/x-www-form-urlencoded'

答案 2 :(得分:8)

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

但jquery中的“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   header起源于请求   服务器。该服务包括一些   标题如   Access-Control-Allow-Origin to   表明这样的请求是否是   允许的。

     

对于BOSH连接管理器,它   足以指明所有的起源   允许,通过设置值   Access-Control-Allow-Origin为*。该   Content-Type标头也必须是   白名单中的   Access-Control-Allow-Headers标头。

     

最后,对于某些类型的   请求,包括BOSH连接   经理请求,权限   支票将被预先通过。该   浏览器将执行OPTIONS请求   期望得到一些HTTP标头   这表明哪些来源   允许,允许哪些方法,   这个授权会持续多长时间   持续。例如,这是什么   旁遮普和ejabberd补丁我做了   返回OPTIONS:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type 
Access-Control-Max-Age: 86400

答案 3 :(得分:0)

Cors在完成请求方法之前,将其从POST更改为OPTIONS,因此,您的发布数据将不会发送。 解决此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#服务器上具有以下标头:

                    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", "*");

答案 4 :(得分:-4)

通过以下方式修改您的Jquery:

$.ajax({
            url: someurl,
            contentType: 'application/json',
            data: JSONObject,
            headers: { 'Access-Control-Allow-Origin': '*' }, //add this line
            dataType: 'json',
            type: 'POST',                
            success: function (Data) {....}
});