Uma solicitação CORS POST funciona a partir do javascript simples, mas por que não com o jQuery?

Eu estou tentando fazer um pedido de pós Cross Origin, e eu tenho que trabalhar em JavaScript simples como este:

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); 

Mas eu gostaria de usar o jQuery, mas não consigo fazê-lo funcionar. É isso que estou tentando:

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

Isso resulta em falha. Se alguém souber por que o jQuery não funciona, informe-nos. Obrigado.

(Estou usando o jQuery 1.5.1 e o Firefox 4.0, e meu servidor está respondendo com um header apropriado Access-Control-Allow-Origin)

ATUALIZAÇÃO: Como TimK apontou, isso não é mais necessário com o jQuery 1.5.2. Mas se você quiser adicionar headers personalizados ou permitir o uso de credenciais (nome de usuário, senha ou cookies, etc.), continue lendo.


Eu acho que encontrei a resposta! (4 horas e muita maldição depois)

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

Você precisa especificar manualmente todos os headers que você aceitará (pelo menos esse foi o caso para mim no FF 4.0 e no Chrome 10.0.648.204).

O método $ .ajax do jQuery envia o header “x-requested-with” para todas as solicitações entre domínios (acho que é apenas um domínio cruzado).

Portanto, o header faltante necessário para responder à solicitação OPTIONS é:

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

Se você está passando headers não “simples”, você precisará incluí-los na sua lista (eu envio mais um):

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

Então, para juntar tudo, aqui está o meu 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); } 

Outra possibilidade é que a configuração de dataType: json faça com que o JQuery envie o header Content-Type: application/json . Isso é considerado um header não padrão pelo CORS e requer uma solicitação de preflight do CORS. Então, algumas coisas para tentar:

1) Tente configurar seu servidor para enviar as respostas corretas de pré-impressão. Isso será na forma de headers adicionais, como Access-Control-Allow-Methods e Access-Control-Allow-Headers .

2) Solte a configuração de dataType: json . O JQuery deve solicitar o Content-Type: application/x-www-form-urlencoded por padrão, mas só para ter certeza, você pode replace o dataType: json por contentType: 'application/x-www-form-urlencoded'

Você está enviando “params” em js: request.send(params);

mas “dados” no jquery “. Os dados são definidos ? data:data,

Além disso, você tem um erro no URL:

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

Você está misturando a syntax com a de $ .post


Update : Eu estava pesquisando com base na resposta do monsur, e descobri que você precisa adicionar Access-Control-Allow-Headers: Content-Type (abaixo está o parágrafo completo)

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

Como funciona o CORS

O CORS funciona de maneira muito semelhante ao arquivo crossdomain.xml do Flash. Basicamente, o navegador enviará uma solicitação de domínio cruzado para um serviço, configurando o header HTTP Origem para o servidor solicitante. O serviço inclui alguns headers como Access-Control-Allow-Origin para indicar se tal solicitação é permitida.

Para os gerenciadores de conexões BOSH, basta especificar que todas as origens são permitidas, configurando o valor de Access-Control-Allow-Origin como *. O header Content-Type também deve ser listado em branco no header Access-Control-Allow-Headers.

Por fim, para determinados tipos de solicitações, incluindo solicitações do gerenciador de conexões BOSH, a verificação de permissions será pré-controlada. O navegador fará uma solicitação OPTIONS e espera recuperar alguns headers HTTP que indicam quais origens são permitidas, quais methods são permitidos e por quanto tempo essa autorização durará. Por exemplo, aqui está o que os patches Punjab e ejabberd eu retornei para OPTIONS:

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