La solicitud de publicación de intercambio de recursos entre orígenes (CORS) funciona desde javascript simple, pero ¿por qué no con jQuery?
Tengo una máquina en mi LAN local (máquinaA) que tiene dos servidores web. El primero es el integrado en XBMC (en el puerto 8080) y muestra nuestra biblioteca. El segundo servidor es un script de Python CherryPy (puerto 8081) que estoy usando para activar una conversión de archivos a pedido. La conversión del archivo se activa mediante una solicitud POST AJAX de la página servida desde el servidor XBMC.
- Vaya a http://machineA:8080 que muestra la biblioteca
- Se muestra la biblioteca
- El usuario hace clic en el enlace 'convertir' que emite el siguiente comando:
Solicitud jQuery Ajax
$.post('http://machineA:8081', {file_url: 'asfd'}, function(d){console.log(d)})
- El navegador emite una solicitud de OPCIONES HTTP con los siguientes encabezados;
Encabezado de solicitud: OPCIONES
Host: machineA:8081
User-Agent: ... Firefox/4.01
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Origin: http://machineA:8080
Access-Control-Request-Method: POST
Access-Control-Request-Headers: x-requested-with
- El servidor responde con lo siguiente;
Encabezado de respuesta: OPCIONES (ESTADO = 200 OK)
Content-Length: 0
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 1728000
Server: CherryPy/3.2.0
Date: Thu, 21 Apr 2011 22:40:29 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Content-Type: text/html;charset=ISO-8859-1
- Entonces la conversación se detiene. En teoría, el navegador debería emitir una solicitud POST cuando el servidor respondió con los encabezados CORS correctos (?) (Access-Control-Allow-Origin: *)
Para solucionar problemas, también emití el mismo comando $.post desde http://jquery.com . Aquí es donde estoy perplejo, desde jquery.com, la solicitud de publicación funciona, se envía una solicitud de OPCIONES seguida de una POST. Los encabezados de esta transacción se encuentran a continuación;
Encabezado de solicitud: OPCIONES
Host: machineA:8081
User-Agent: ... Firefox/4.01
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Origin: http://jquery.com
Access-Control-Request-Method: POST
Encabezado de respuesta: OPCIONES (ESTADO = 200 OK)
Content-Length: 0
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 1728000
Server: CherryPy/3.2.0
Date: Thu, 21 Apr 2011 22:37:59 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Content-Type: text/html;charset=ISO-8859-1
Encabezado de solicitud: POST
Host: machineA:8081
User-Agent: ... Firefox/4.01
Accept: */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://jquery.com/
Content-Length: 12
Origin: http://jquery.com
Pragma: no-cache
Cache-Control: no-cache
Encabezado de respuesta: POST (ESTADO = 200 OK)
Content-Length: 32
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 1728000
Server: CherryPy/3.2.0
Date: Thu, 21 Apr 2011 22:37:59 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Content-Type: application/json
No puedo entender por qué la misma solicitud funcionaría en un sitio, pero no en el otro. Espero que alguien pueda señalar lo que me estoy perdiendo. ¡Gracias por tu ayuda!
Finalmente me topé con este enlace " Una solicitud CORS POST funciona desde javascript simple, pero ¿por qué no con jQuery? " que señala que jQuery 1.5.1 agrega el
Access-Control-Request-Headers: x-requested-with
encabezado a todas las solicitudes CORS. jQuery 1.5.2 no hace esto. Además, según la misma pregunta, configurar un encabezado de respuesta del servidor de
Access-Control-Allow-Headers: *
no permite que la respuesta continúe. Debe asegurarse de que el encabezado de respuesta incluya específicamente los encabezados requeridos. es decir:
Access-Control-Allow-Headers: x-requested-with
PEDIDO:
$.ajax({
url: "http://localhost:8079/students/add/",
type: "POST",
crossDomain: true,
data: JSON.stringify(somejson),
dataType: "json",
success: function (response) {
var resp = JSON.parse(response)
alert(resp.status);
},
error: function (xhr, status) {
alert("error");
}
});
RESPUESTA:
response = HttpResponse(json.dumps('{"status" : "success"}'))
response.__setitem__("Content-type", "application/json")
response.__setitem__("Access-Control-Allow-Origin", "*")
return response
Resolví mi propio problema al utilizar la API de matriz de distancia de Google configurando el encabezado de mi solicitud con Jquery ajax. echa un vistazo a continuación.
var settings = {
'cache': false,
'dataType': "jsonp",
"async": true,
"crossDomain": true,
"url": "https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins=place_id:"+me.originPlaceId+"&destinations=place_id:"+me.destinationPlaceId+"®ion=ng&units=metric&key=mykey",
"method": "GET",
"headers": {
"accept": "application/json",
"Access-Control-Allow-Origin":"*"
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
Tenga en cuenta lo que agregué en la configuración
**
"headers": {
"accept": "application/json",
"Access-Control-Allow-Origin":"*"
}
**
Espero que esto ayude.
Me tomó algo de tiempo encontrar la solución.
En caso de que su servidor responda correctamente y la solicitud sea el problema, debe agregar withCredentials: true
a xhrFields
la solicitud:
$.ajax({
url: url,
type: method,
// This is the important part
xhrFields: {
withCredentials: true
},
// This is the important part
data: data,
success: function (response) {
// handle the response
},
error: function (xhr, status) {
// handle errors
}
});
Nota: se requiere jQuery >= 1.5.1