Estoy tratando de hacer una solicitud de publicación de Cross Origin, y lo hice funcionar en forma simple JavaScript
así:
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);
Pero me gustaría usar jQuery
, pero no puedo hacer que funcione. Esto es lo que estoy intentando:
$.ajax(url, {
type:"POST",
dataType:"json",
data:{action:"something"},
success:function(data, textStatus, jqXHR) {alert("success");},
error: function(jqXHR, textStatus, errorThrown) {alert("failure");}
});
Esto resulta en una falla. Si alguien sabe por qué jQuery
no funciona, háganoslo saber. Gracias.
(Estoy usando jQuery
1.5.1 y Firefox 4.0, y mi servidor responde con un Access-Control-Allow-Origin
encabezado adecuado )
javascript
jquery
xmlhttprequest
cors
Magmático
fuente
fuente
Respuestas:
ACTUALIZACIÓN: Como señaló TimK, esto ya no es necesario con jquery 1.5.2. Pero si desea agregar encabezados personalizados o permitir el uso de credenciales (nombre de usuario, contraseña o cookies, etc.), siga leyendo.
¡Creo que encontré la respuesta! (4 horas y muchas maldiciones después)
//This does not work!! Access-Control-Allow-Headers: *
Debe especificar manualmente todos los encabezados que aceptará (al menos ese fue mi caso en FF 4.0 y Chrome 10.0.648.204).
El método $ .ajax de jQuery envía el encabezado "x-required-with" para todas las solicitudes de dominio cruzado (creo que es el único dominio cruzado).
Entonces, el encabezado faltante necesario para responder a la solicitud de OPCIONES es:
//no longer needed as of jquery 1.5.2 Access-Control-Allow-Headers: x-requested-with
Si está pasando encabezados que no sean "simples", deberá incluirlos en su lista (le envío uno más):
//only need part of this for my custom header Access-Control-Allow-Headers: x-requested-with, x-requested-by
Entonces, para ponerlo todo junto, aquí está mi 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); }
fuente
Otra posibilidad es que la configuración
dataType: json
haga que JQuery envíe elContent-Type: application/json
encabezado. Esto se considera un encabezado no estándar por CORS y requiere una solicitud de verificación previa de CORS. Así que algunas cosas para probar:1) Intente configurar su servidor para enviar las respuestas de verificación previa adecuadas. Esto tendrá la forma de encabezados adicionales como
Access-Control-Allow-Methods
yAccess-Control-Allow-Headers
.2) Elimine la
dataType: json
configuración. JQuery debería solicitarContent-Type: application/x-www-form-urlencoded
de forma predeterminada, pero solo para estar seguro, puede reemplazardataType: json
concontentType: 'application/x-www-form-urlencoded'
fuente
application/x-www-form-urlencoded
e inclusotext/plain
. E intenté agregar un encabezado de respuesta deAccess-Control-Allow-Methods "POST, GET, OPTIONS"
Nada funcionó.dataType
influye en elAccept
encabezado de la solicitud, pero no en elContent-Type
encabezado de la solicitud.Estás enviando "params" en js:
request.send(params);
pero "datos" en jquery ". ¿Los datos están definidos ?:
data:data,
Además, tiene un error en la URL:
$.ajax( {url:url, type:"POST", dataType:"json", data:data, success:function(data, textStatus, jqXHR) {alert("success");}, error: function(jqXHR, textStatus, errorThrown) {alert("failure");} });
Estás mezclando la sintaxis con la de $ .post
Actualización : estaba buscando en Google según la respuesta de monsur, y descubrí que necesita agregar
Access-Control-Allow-Headers: Content-Type
(a continuación se muestra el párrafo completo)http://metajack.im/2010/01/19/crossdomain-ajax-for-xmpp-http-binding-made-easy/
fuente
var data = {action:"something"}
jQuery.ajaxSetup({'beforeSend': function(xhr) {xhr.setRequestHeader(string, string)}})
y jugar con los diferentes encabezados enviados (un ejemplo de rieles aquí: railscasts.com/episodios/136-jquery )Cors cambia el método de solicitud antes de que se haga, de POST a OPTIONS, por lo que no se enviarán los datos de tu publicación. La forma en que funcionó para manejar este problema de cors es realizar la solicitud con ajax, que no admite el método OPTIONS. código de ejemplo:
$.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); } });
con estos encabezados en el 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", "*");
fuente
Modifique su Jquery de la siguiente manera:
$.ajax({ url: someurl, contentType: 'application/json', data: JSONObject, headers: { 'Access-Control-Allow-Origin': '*' }, //add this line dataType: 'json', type: 'POST', success: function (Data) {....} });
fuente
contentType: 'application/json', data: JSONObject,
- El servidor no espera JSON, por lo que enviar JSON no tendría sentido. Además, no existe un objeto JSON .headers: { 'Access-Control-Allow-Origin': '*' }, //add this line
- Nunca hagas eso.Access-Control-Allow-Origin
es un encabezado de respuesta , no un encabezado de solicitud. En el mejor de los casos, esto no hará nada. En el peor de los casos, convertirá la solicitud de una solicitud simple a una solicitud de verificación previa, lo que hace que sea cada vez más difícil de tratar en el servidor.