2008-12-02 13 views
22

Necesito realizar una solicitud AJAX desde un sitio web a un servicio web REST alojado en otro dominio.Solicitudes AJAX entre sitios

Aunque esto funciona muy bien en Internet Explorer, otros navegadores como Mozilla y Google Chrome imponen restricciones de seguridad mucho más estrictas, que prohíben las solicitudes AJAX entre sitios.

El problema es que no tengo control sobre el dominio ni el servidor web donde se aloja el sitio. Esto significa que mi servicio web REST debe ejecutarse en otro lugar, y no puedo implementar ningún mecanismo de redirección.

Aquí está el código JavaScript que hace que la llamada asincrónica:

var serviceUrl = "http://myservicedomain"; 
var payload = "<myRequest><content>Some content</content></myRequest>"; 
var request = new XMLHttpRequest(); 
request.open("POST", serviceUrl, true); // <-- This fails in Mozilla Firefox amongst other browsers 
request.setRequestHeader("Content-type", "text/xml"); 
request.send(payload); 

¿Cómo puedo tener este trabajo en otros navegadores junto a Internet Explorer?

+1

@PhiLho En este caso, mi objetivo es invocar un servicio REST alojado en un dominio diferente, sin incluir contenido dinámico. –

Respuesta

14

tal vez JSONP puede ayudar.

NB sus tendrá que cambiar sus mensajes a utilizar JSON en lugar de XML

Editar

Principales sitios como Flickr y twitter jsonp apoyo con devoluciones de llamada, etc

+0

esto podría funcionar, pero JSONP es una admisión de que algo está mal :) – annakata

+0

¿Qué tan popular es este enfoque? Parece un poco experimental –

+0

@annakata, obviamente, pero se metnionó que no tiene control sobre el servidor web, etc. por lo que usar un proxy está fuera de la ventana. No estoy aquí para comentar sobre su situación solo proporcionar una posible solución a su pregunta/problema. – redsquare

3

El hecho de que esto funciona en IE es un problema de seguridad con IE, no una función.

Lamentablemente, se prohíbe la creación de secuencias de comandos entre sitios, y la alternativa aceptada es realizar un proxy de las solicitudes a través de su propio dominio: ¿realmente no tiene la capacidad de agregar o modificar el código del servidor?

Además, la solución alternativa (que implica la adquisición de datos mediante etiquetas de script) solo admitirá solicitudes GET, que podría piratear con un servicio SOAP, pero no tanto con la solicitud POST a un RESTful servicio que describes

Realmente no estoy seguro de que exista una solución AJAX, es posible que haya vuelto a una solución de < >.

+0

Estoy de acuerdo en que permitir XSS es un error de seguridad en IE. Lamentablemente, no tengo ningún control sobre el servidor web, ya que es un blog alojado en un proveedor de terceros. También pensé en usar formularios HTML, pero eso causaría una publicación de página completa en lugar de una buena llamada asincrónica. –

3

La solución no muy clara (pero funciona) es utilizar iframe como contenedor para solicitudes a otros sitios. El problema es que el padre no puede acceder al contenido de iframe, solo puede navegar el atributo "src" de iframe. Pero el contenido del iframe puede acceder al contenido de los padres.

Por lo tanto, si el contenido del iframe lo sabe, pueden llamar a algún contenido de JavaScript en la página principal o directamente acceder al DOM de los padres.

EDIT: muestra:

function ajaxWorkaroung() { 
    var frm = gewtElementById("myIFrame") 
    frm.src = "http://some_other_domain" 
} 
function ajaxCallback(parameter){ 
    // this function will be called from myIFrame's content 
} 
+2

IFrames son más lentos que ajax, y también en IE más antiguo Recuerdo que hay un sonido de 'clic' jugado cada iframe.src update :( – Thinker

+0

En javascript no se puede acceder a los datos o funciones padre cros-domain. La respuesta es falsa – naugtur

+0

@nagtur: utilicé este escenario hace tiempo: – TcKs

5

El mensaje marcado como la respuesta es errónea: el documento iframes no es capaz de acceder a los padres. La misma política de origen funciona en ambos sentidos.

El hecho es que no es posible de ninguna manera consumir un servicio web basado en el resto usando xmlhttprequest. La única manera de cargar datos desde un dominio diferente (sin ningún marco) es usar JSONP. Cualquier otra solución requiere un proxy en el servidor ubicado en su propio dominio, o un proxy del lado del cliente ubicado en el dominio remoto y algún tipo de comunicación entre sitios (como easyXDM) para comunicarse entre los documentos.

+0

-1 porque no es impreciso. Es posible acceder a la página principal desde un IFRAME con JavaScript utilizando el objeto DOM "principal". ejemplo, esto modificará un elemento en la página dentro de un IFRAME: parent.document.getElementById ("someDiv"). innerHTML = "some content"; –

+2

La pregunta es sobre el documento de diferentes dominios, y la misma política de origen será por lo tanto efecto. Un IFrame de domainA no puede acceder al contentDocument de su padre si el padre es de domainB. Como el autor de la easyXSS biblioteca entre sitios, tengo algo de conocimiento sobre esto. –

+0

No entendí tu respuesta entonces. Tiene razón, un iframe no puede acceder al contenido de la página principal y viceversa cuando los dos se alojan en dominios diferentes. Sin embargo, en mi caso, usar un iframe funciona bien, porque no necesita acceder a la página principal de ninguna manera, sino que simplemente publica una solicitud AJAX en un servicio alojado en su mismo dominio. –

2

Haga que su dominio de servicio acepte compartir recursos de origen cruzado (CORS).

Escenario típico: la mayoría de los navegadores compatibles con CORS enviarán primero un encabezado OPTIONS, al que el servidor debe devolver información sobre qué encabezados se aceptan. Si los encabezados satisfacen los requisitos del servicio para la solicitud proporcionada (métodos permitidos son GET y POST, Allowed-Origin *, etc.), el navegador reenviará la solicitud con el método apropiado (GET, POST, etc.).

Todo este punto a seguir es el mismo que cuando se usa IE, o más simplemente, si se está publicando en el mismo dominio.

Caviots: Algunos SDK de desarrollo de servicios (WCF en particular) intentarán procesar la solicitud, en cuyo caso debe preprocesar el método OPTIONS para responder a la solicitud y evitar que el método se llame dos veces en el servidor.

En resumen, el problema reside en el servidor.

Editar Hay un problema con IE 9 y con CORS, ya que no está completamente implementado. Por suerte, puede resolver este problema al hacer sus llamadas de código del lado del servidor para el servicio y tienen que volver a través de su servidor (por ejemplo MyPage.aspx? = Bla servicio & method = blahblah & p0 = = firstParam algo). A partir de aquí, su código del lado del servidor debería implementar un modelo de secuencia de solicitud/respuesta.

0

Esto también se puede hacer utilizando una configuración de servidor web necesitas cigarros que llama rizo con los argumentos correctos y devuelve la salida de rizo.

app.rb

require 'sinatra' 
require 'curb' 

set :views,lambda {"views/"+self.name.to_s.downcase.sub("controller","")} 
set :haml, :layout => :'../layout', :format => :html5, :escape_html=>true 
disable :raise_errors 

get '/data/:brand' do 
    data_link = "https://externalsite.com/#{params[:brand]}" 
    c = Curl::Easy.perform(data_link) 
    c.body_str 
end 

envío de una petición AJAX a localhost: 4567/datos/algo va a devolver el resultado de externalsite.com/something.

0

Otra opción sería la de configurar un registro CNAME en su propio dominio para "enmascarar" el nombre de host de dominio remoto.

Cuestiones relacionadas