2011-05-09 33 views
9

Hay varios temas sobre el problema con AJAX entre dominios. Los he estado buscando y la conclusión parece ser la siguiente:POST ajax de dominio cruzado en cromo

Además de usar algo como JSONP, o una solución de proxy, no debería poder hacer un jquery básico $ .post() a otro dominio

:

Mi código de prueba es como la siguiente (que se ejecuta en "http://myTestdomain.tld/path/file.html")

var myData = {datum1 : "datum", datum2: "datum"} 
$.post("http://External-Ip:port", myData,function(return){alert(return);}); 

Cuando probé esto (la razón por la que empecé a buscar), cromo-consola me dijo

XMLHttpRequest no se puede cargar . Origen http://myTestdomain.tld no está permitido por Access-Control-Allow-Origin.

Ahora bien, esto es, por lo que puedo decir, esperado. No debería ser capaz de hacer esto. El problema es que el POST en realidad SI viene a través. Tengo un script simple en ejecución que guarda el $_POST en un archivo, y está claro que la publicación se abre. Los datos reales que devuelvo no se entregan a mi secuencia de comandos de llamada, lo que de nuevo parece esperado debido al problema de control de acceso. Pero el hecho de que el mensaje realmente llegó al servidor me confundió.

  • ¿Es cierto que supongo que el código de seguridad que se ejecuta en "myTestdomain" no debería ser capaz de hacer un simple $.post() al otro dominio (Externo-IP)?
  • ¿Se espera que la solicitud realmente llegue al script de la IP externa, aunque no se reciba la salida? o es esto un error. (Estoy usando Chrome 11.0.696.60)
+0

Esto significa que protege contra (algunos) exploits XSS, pero no CSRF? Me parece extraño de todos modos: P – markijbema

+0

Me retracto de mi comentario según la respuesta de Michiels, en realidad tiene sentido en cuanto a la seguridad. – markijbema

+0

puede probar esto [EXTENSIÓN DEL CROMO] (https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=es) – kplshrm7

Respuesta

5

Publiqué un boleto sobre esto en el rastreador de errores WebKit anteriormente, ya que pensé que era un comportamiento extraño y posiblemente un riesgo para la seguridad.

Desde entradas relacionadas con la seguridad no se pueden ver públicamente, citaré la respuesta de Justin Schuh aquí:

Esto se implementa exactamente como es requerido por la especificación. Para solicitudes simples de origen cruzado http://www.w3.org/TR/cors/#simple-method> no hay verificación previa al vuelo; se realiza la solicitud y la respuesta no puede leerse si los encabezados apropiados no autorizan el origen solicitante. Funcionalmente, esto no es diferente a crear un formulario y usar un script para crear un POST fuera de origen (que siempre ha sido posible).

Así que: puedes hacer el POST ya que podrías haberlo hecho de todos modos al insertar un formulario y activando el botón de enviar con javascript, pero no puedes ver el resultado. Porque no sería capaz de hacer eso en el escenario de formulario.

Una solución sería agregar un encabezado al script que se ejecuta en el servidor de destino, p.

<?php 
header("Access-Control-Allow-Origin: http://your_source_domain"); 
.... 
?> 

No lo he probado, pero de acuerdo con la especificación, eso debería funcionar.

Firefox 3.6 parece manejarlo de manera diferente, primero haciendo una OPCIONES para ver si puede o no hacer el POST actual. Firefox 4 hace lo mismo que Chrome, o al menos lo hizo en mi experimento rápido. Más sobre eso está en https://developer.mozilla.org/en/http_access_control

+0

Esto significa que aunque (según la respuesta de Justin Schuh) parece lógico que puedas hacer la publicación, no hay garantía, ya que algunos navegadores (Firefox en tu ejemplo) en realidad no te permiten hacer esto. – Nanne

+0

Lo intenté antes con FF 3.6 que no me permitió hacerlo (en su lugar, OPTIONS). Justo ahora lo intenté con FF 4.0, que * no * permitió la solicitud (de la misma manera que lo hace Chrome/Safari, sin permitirte ver el resultado). – Marlies

+0

@Nanne @Michiel La solicitud OPTIONS que está viendo se debe a la verificación previa: si realiza una solicitud POST con encabezados personalizados o un tipo de contenido configurado en algo distinto a 'application/x-www-form-urlencoded, multipart/form -data', o 'text/plain', el navegador intenta asegurarse de que se permita una solicitud con esos encabezados haciendo una solicitud OPTIONS antes de realizar la solicitud POST real. –

3

Lo importante a tener en cuenta sobre la restricción JavaScript same-origin policy es que es algo integrado en los navegadores modernos para la seguridad - no es una limitación de la tecnología o algo impuesto por servidores.

Para responder a su pregunta, ninguno de estos son errores.

  • Las solicitudes no se detienen lleguen al servidor - esto le da al servidor de la opción de permitir que estas peticiones entre dominios mediante el establecimiento de las cabeceras apropiadas 1.

  • La respuesta también la recibe el navegador. Antes del uso de los encabezados de control de acceso 1, las respuestas a las solicitudes de dominios cruzados se detenían en seco por un navegador con control de seguridad: el navegador recibiría la respuesta pero no la entregaría al script. Con los encabezados de control de acceso, el servidor tiene la opción de configurar los encabezados apropiados que indican a un navegador compatible que le gustaría permitir que ciertas URL de origen realicen solicitudes de dominio cruzado.

    El comportamiento exacto de la respuesta puede variar entre los navegadores. No puedo recordarlo con certeza ahora, pero creo que Chrome llama a la función de devolución de llamada success cuando usa jQuery's ajax() pero la respuesta está vacía. IIRC, Firefox no invocará la función success.

+0

Hmm, estoy confundido. ¿Cuál sería el uso para establecer los encabezados como "no permitido", pero aún así ejecutar el script? Esto significa que puedo hacer mi publicación (lo cual es bueno), aunque la política del mismo origen me impide manejarla como lo haría con una solicitud del mismo dominio. ¿Me estoy perdiendo de algo? – Nanne

+0

@Nanne Se permitirá que su JavaScript se ejecute y realice la solicitud: la solicitud pasará al servidor pero su JS puede o no recibir la respuesta. Si el servidor establece el encabezado que permite que ese dominio (el origen) realice la solicitud entre dominios, un navegador más nuevo que admita el encabezado de control de acceso permitirá que la respuesta pase a su JS.Si es un navegador que no entiende este mecanismo de permitir CDR o si el servidor no establece el encabezado que permite ese origen, su JS no obtendrá una respuesta. ¿Eso ayuda a aclarar? –

0

Me pasa lo mismo que a mí. Puede publicar en todos los dominios pero no puede recibir una respuesta. Esto es lo que esperaba poder hacer y me sucede en Firefox, Chrome e IE.

Una forma de eludir esta advertencia es tener un archivo php local que invoque los datos mediante curl y responda la respuesta a su javascript. (Algo así reiteró lo que dijo que ya lo sabía.)

+0

¿Por qué esperas este comportamiento? Si los encabezados están configurados para que la solicitud no sea válida, esperaría que el script no se ejecute. Algo así como: establecer el encabezado "no permitido" y luego enviar algo negativo/falso hacia atrás. Pero aparentemente esto no sucede :) – Nanne

+0

He utilizado esta capacidad para enviar datos, como un enlace a un sistema diferente. Este enlace se usa para descargar el archivo a un servidor separado pero no requiere respuesta al script. Lo extraño que he notado es que los encabezados que se devuelven tienen la duración adecuada del contenido, pero simplemente elimina los datos. Esperaría que lo bloqueara todo, así que ni siquiera veo la respuesta del encabezado. –

+0

sí, eso es exactamente lo que veo. No lo esperaba :) – Nanne

0
  1. Sí, es correcto y que no será capaz de hacer eso a menos que utilice cualquier proxy.

  2. No, la solicitud no irá a la IP externa tan pronto como exista dicha limitación.

+0

aunque había un truco para Firefox que una vez había intentado superar este problema para fines de prueba. Encontré una solución para Chrome pero nunca funcionó. – Neutralizer

+0

Bueno, eso significa que el punto 2 es un error, porque puedo confirmar que llega a la IP. – Nanne

+0

No está correcto en el n. ° 2, ya que está permitido; de lo contrario, las soluciones como los encabezados de control de acceso (vinculados a en mi respuesta) no funcionarían. Las restricciones de dominio cruzado son 'artificiales' en el sentido de que se agregaron a los navegadores como medida de seguridad y no a causa de una incapacidad inherente para realizar tales solicitudes. Como tal, las solicitudes y las respuestas aparecerán a través del cable, es solo su código JS que no verá la respuesta porque el navegador lo detendrá. –

Cuestiones relacionadas