Ajax cross-domain

Una de las principales limitaciones de Ajax esta en que no se pueden realizar peticiones a otro dominio. Cuando intentamos realizar una petición a un servidor fuera del dominio, obtenemos un error de seguridad 101.

Uncaught Error: NETWORK_ERR: XMLHttpRequest Exception 101

Esto es realmente un dolor de cabeza cuando estamos trabajando localmente contra servidores de desarrollo o productivos, porque no nos permite realizar una petición.

Existen 2 maneras bastante eficientes para solucionar este problema.

Encapsulado

JavaScript también tiene sus limitaciones, pero permite cargar código javaScript desde otro dominio. Por lo tanto, una de las maneras es encapsular los mensajes a través de funciones, pero también necesitamos tener acceso a modificar archivos en el servidor. jQuery provee una forma muy simple de solucionarlo.

$.ajax({
	url : 'http://www.segundo-dominio.com',
	dataType : 'jsonp',
	data : data
});

La magia se produce en situar jsonp como datatype en lugar de json. De esta manera le estamos diciendo a jQuery que será una petición cross-domain. Sin embargo esto no es todo. El server también debe estar preparado. En este caso vamos a utilizar PHP para la respuesta y tendremos que identificar cuando una petición es cross-domain(5) o no. Si es una petición en el mismo dominio, no tendríamos que encapsular el resultado (7).

 

Cuando le decimos a jQuery que realice una petición cross-domain, lo que hace es encapsular la información agregando la información que obtenemos luego mediante $_GET['callback']. Este parámetro contiene el encabezado jQuery[requestID]. Es por eso, que hay que devolver los resultados incluyendo esta información y los resultados a continuación encerrados entre parentesis. La respuesta para este caso, podría ser algo parecido a esto:

jQuery1784542312313245_797687424({"Employee":"John Doe"});

Redireccionamiento

La otra manera de enfrentar este problema sin la utilización de JSONP, es creando una re-dirección interna.
Si la llamada es a la siguiente URL:

http://www.segundo-dominio.com/jsondisplay?id=452435

Aquí nos enfrentamos a 2 problemas. Primero como ya dijimos, esta fuera de nuestro dominio y segundo que recibe parámetros.
Lo que haremos es un archivo en nuestro servidor que recibirá por la url, la dirección solicitada:

// redir.php

De modo que ahora corresponde escribir el código javascript para realizar la llamada.

// Función cross browser para crear el objeto XHR
function getXHR(){
	var xhr=false;
	try {
		xhr = new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e) {
		try {
			xhr = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (E) {
			xhr = false;
		}
	}
	if (!xhr && typeof XMLHttpRequest != 'undefined') {
		xhr = new XMLHttpRequest();
	}
	return xhr;
};
 
var getdetails = function(id) {
	var xhr = getXHR();
	var cUri = "http://www.segundo-dominio.com/jsondisplay?id=452435";
	cUri = "redir.php?url=" + encodeURIComponent( cUri );
	xhr.onreadystatechange= function() {
		if (this.readyState !== 4) return; // not ready yet
		if (this.status == 200) { // HTTP 200 OK
			alert( this.responseText );
		} else {
			// server returned an error. Do something with it or ignore it
		}
	};
	xhr.open( "GET", cUri, false );
	xhr.send(); 
};

La primer función solo crea el objeto xhr, mientras que en la segunda, solo llamamos a un archivo PHP que esta en el mismo dominio donde se ejecuta el código AJAX. El archivo PHP lo que hace es capturar la respuesta de la URL y pasarla al objeto XHR que creamos.

Verán que para pasar la URL como parametro GET, desde javascript se códifica y luego se decodifica en PHP. Esto es sumamente importante si es que no quieren enfrentarse a errores.

Si bien hemos utilizado PHP para este ejemplo, podríamos realizarlo en cualquier lenguaje.