Estou tentando fazer uma solicitação de postagem Cross Origin, e consegui funcionar da JavaScript
seguinte maneira:
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 jQuery
, mas não consigo fazer funcionar. Isso é o 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 jQuery
que não funciona, entre em contato conosco. Obrigado.
(Estou usando jQuery
1.5.1 e Firefox 4.0, e meu servidor está respondendo com um Access-Control-Allow-Origin
cabeçalho adequado )
javascript
jquery
xmlhttprequest
cors
Magmático
fonte
fonte
Respostas:
ATUALIZAÇÃO: como TimK apontou, isso não é mais necessário com jquery 1.5.2. Mas se você deseja adicionar cabeçalhos personalizados ou permitir o uso de credenciais (nome de usuário, senha ou cookies, etc.), continue lendo.
Acho que encontrei a resposta! (4 horas e muitos palavrões depois)
//This does not work!! Access-Control-Allow-Headers: *
Você precisa especificar manualmente todos os cabeçalhos que deseja aceitar (pelo menos esse era o meu caso no FF 4.0 e no Chrome 10.0.648.204).
O método $ .ajax do jQuery envia o cabeçalho "x-required-with" para todas as solicitações de domínio cruzado (acho que é apenas domínio cruzado).
Portanto, o cabeçalho ausente 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ê estiver passando quaisquer cabeçalhos não "simples", precisará incluí-los em sua lista (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 colocar tudo junto, aqui está 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); }
fonte
Outra possibilidade é que a configuração
dataType: json
faça com que o JQuery envie oContent-Type: application/json
cabeçalho. Isso é considerado um cabeçalho não padrão pelo CORS e requer uma solicitação de comprovação do CORS. Então, algumas coisas para tentar:1) Tente configurar seu servidor para enviar as respostas de comprovação adequadas. Isso estará na forma de cabeçalhos adicionais como
Access-Control-Allow-Methods
eAccess-Control-Allow-Headers
.2) Abandone o
dataType: json
configuração. JQuery deve solicitarContent-Type: application/x-www-form-urlencoded
por padrão, mas apenas para ter certeza, você pode substituirdataType: json
porcontentType: 'application/x-www-form-urlencoded'
fonte
application/x-www-form-urlencoded
e uniformetext/plain
. E tentei adicionar um cabeçalho de resposta deAccess-Control-Allow-Methods "POST, GET, OPTIONS"
Nada funcionou.dataType
influencia oAccept
cabeçalho da solicitação, mas não oContent-Type
cabeçalho da solicitação.Você está enviando "params" em js:
request.send(params);
mas "dados" em jquery ". Os dados estã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 sintaxe com a de $ .post
Atualização : eu estava pesquisando com base na resposta de 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/
fonte
var data = {action:"something"}
jQuery.ajaxSetup({'beforeSend': function(xhr) {xhr.setRequestHeader(string, string)}})
e brincar com os diferentes cabeçalhos enviados (um exemplo para rails aqui: railscasts.com/episodes/136-jquery )Cors muda o método de solicitação antes de terminar, de POST para OPTIONS, portanto, seus dados de postagem não serão enviados. A maneira que funcionou para lidar com esse problema de cors é executando a solicitação com ajax, que não suporta o método OPTIONS. código de exemplo:
$.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); } });
com estes cabeçalhos no servidor 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", "*");
fonte
Modifique seu Jquery da seguinte maneira:
$.ajax({ url: someurl, contentType: 'application/json', data: JSONObject, headers: { 'Access-Control-Allow-Origin': '*' }, //add this line dataType: 'json', type: 'POST', success: function (Data) {....} });
fonte
contentType: 'application/json', data: JSONObject,
- O servidor não está esperando JSON, portanto, enviar JSON não faria sentido. Além disso, não existe um objeto JSON .headers: { 'Access-Control-Allow-Origin': '*' }, //add this line
- Nunca faça isso.Access-Control-Allow-Origin
é um cabeçalho de resposta , não um cabeçalho de solicitação. Na melhor das hipóteses, isso não fará nada. Na pior das hipóteses, ele converterá a solicitação de uma solicitação simples em uma solicitação preflight, o que torna cada vez mais difícil lidar com ela no servidor.