javascript - what - cross domain
Formas de eludir la polĂtica del mismo origen (11)
El método document.domain
- Tipo de método: iframe .
Tenga en cuenta que este es un método de iframe que establece el valor de document.domain en un sufijo del dominio actual. Si lo hace, el dominio más corto se usa para verificaciones de origen posteriores. Por ejemplo, suponga que un script en el documento en http://store.company.com/dir/other.html
ejecuta la siguiente declaración:
document.domain = "company.com";
Después de que se ejecute esa instrucción, la página pasará la comprobación de origen con http://company.com/dir/page.html
. Sin embargo, por el mismo razonamiento, company.com no pudo establecer document.domain
a othercompany.com
.
Con este método, se le permitiría ejecutar javascript desde un iframe de un subdominio en una página originada en el dominio principal. Este método no es adecuado para recursos de dominios cruzados, ya que los navegadores como Firefox no le permitirán cambiar el document.domain
a un dominio completamente ajeno.
Fuente: https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript
El método de intercambio de recursos de origen cruzado
- Tipo de método: AJAX .
Cross-Origin Resource Sharing (CORS) es un borrador de trabajo del W3C que define cómo el navegador y el servidor deben comunicarse al acceder a las fuentes en todos los orígenes. La idea básica detrás de CORS es usar encabezados HTTP personalizados para permitir que tanto el navegador como el servidor conozcan lo suficiente unos de otros para determinar si la solicitud o respuesta debe tener éxito o fallar.
Para una solicitud simple, una que usa GET
o POST
sin encabezados personalizados y cuyo cuerpo es text/plain
, la solicitud se envía con un encabezado adicional llamado Origin
. El encabezado Origen contiene el origen (protocolo, nombre de dominio y puerto) de la página solicitante para que el servidor pueda determinar fácilmente si debe o no servir una respuesta. Un encabezado de Origin
ejemplo podría verse así:
Origin: http://www.stackoverflow.com
Si el servidor decide que la solicitud debe permitirse, envía un encabezado Access-Control-Allow-Origin
eco del mismo origen que se envió o *
si es un recurso público. Por ejemplo:
Access-Control-Allow-Origin: http://www.stackoverflow.com
Si falta este encabezado o los orígenes no coinciden, el navegador no permite la solicitud. Si todo está bien, el navegador procesa la solicitud. Tenga en cuenta que ni las solicitudes ni las respuestas incluyen información de cookies.
El equipo de Mozilla sugiere en su publicación sobre CORS que debe verificar la existencia de la propiedad withCredentials
para determinar si el navegador admite CORS a través de XHR. A continuación, puede XDomainRequest
la existencia del objeto XDomainRequest
para cubrir todos los navegadores:
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
var request = createCORSRequest("get", "http://www.stackoverflow.com/");
if (request){
request.onload = function() {
// ...
};
request.onreadystatechange = handler;
request.send();
}
Tenga en cuenta que para que el método CORS funcione, debe tener acceso a cualquier tipo de mecanismo de cabecera del servidor y no puede acceder simplemente a ningún recurso de terceros.
Fuente: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
El método window.postMessage
- Tipo de método: iframe .
window.postMessage
, cuando se llama, hace que se MessageEvent
un MessageEvent
en la ventana de destino cuando se completa cualquier script pendiente que se debe ejecutar (por ejemplo, los manejadores de eventos restantes si se llama a window.postMessage
desde un controlador de eventos, tiempos de espera pendientes establecidos previamente, etc. ) MessageEvent
tiene el mensaje de tipo, una propiedad de data
que se establece en el valor de cadena del primer argumento proporcionado a window.postMessage
, una propiedad de origin
correspondiente al origen del documento principal en la ventana que llama a window.postMessage
en la window.postMessage
tiempo window.postMessage
se ha llamado a window.postMessage
y una propiedad de source
que es la ventana desde la que se llama a window.postMessage
.
Para usar window.postMessage
, se debe adjuntar un detector de eventos:
// Internet Explorer
window.attachEvent(''onmessage'',receiveMessage);
// Opera/Mozilla/Webkit
window.addEventListener("message", receiveMessage, false);
Y una función receiveMessage
debe ser declarada:
function receiveMessage(event)
{
// do something with event.data;
}
El iframe fuera del sitio también debe enviar eventos correctamente a través de postMessage
:
<script>window.parent.postMessage(''foo'',''*'')</script>
Cualquier ventana puede acceder a este método en cualquier otra ventana, en cualquier momento, independientemente de la ubicación del documento en la ventana, para enviar un mensaje. En consecuencia, cualquier detector de eventos utilizado para recibir mensajes debe verificar primero la identidad del remitente del mensaje, utilizando el origen y posiblemente las propiedades de origen. Esto no se puede subestimar: el hecho de no verificar el origin
y posiblemente las propiedades de source
permite los ataques de secuencias de comandos entre sitios.
Fuente: https://developer.mozilla.org/en/DOM/window.postMessage
La misma política de origen
Quería hacer una wiki de comunidad con respecto a las políticas de origen de HTML / JS para ayudar a cualquiera que busque este tema. Este es uno de los temas más buscados en SO y no hay wiki consolidado para él, así que aquí voy :)
La misma política de origen evita que un documento o script cargado desde un origen obtenga o establezca propiedades de un documento de otro origen. Esta política se remonta a Netscape Navigator 2.0.
¿Cuáles son algunas de sus formas favoritas de evitar las políticas del mismo origen?
Mantenga los ejemplos detallados y preferiblemente también vincule sus fuentes.
El método de proxy inverso
- Tipo de método: Ajax
La configuración de un proxy inverso simple en el servidor permitirá que el navegador utilice rutas relativas para las solicitudes Ajax, mientras que el servidor actuará como proxy en cualquier ubicación remota.
Si se usa mod_proxy en Apache, la directiva de configuración fundamental para configurar un proxy inverso es ProxyPass
. Normalmente se usa de la siguiente manera:
ProxyPass /ajax/ http://other-domain.com/ajax/
En este caso, el navegador podría solicitar /ajax/web_service.xml
como una URL relativa, pero el servidor lo /ajax/web_service.xml
actuando como un proxy para http://other-domain.com/ajax/web_service.xml
.
Una característica interesante de este método es que el proxy inverso puede distribuir fácilmente solicitudes hacia múltiples back-ends, actuando así como un balanceador de carga .
AnyOrigin no funcionó bien con algunos sitios https, así que acabo de escribir una alternativa de código abierto llamada whateverorigin.org que parece funcionar bien con https.
Aquí hay algunas soluciones y explicaciones de la misma política de origen:
Thiru''s Blog: solución de política de origen del mismo navegador
Bueno, utilicé Curl en PHP para eludir esto. Tengo un servicio web ejecutándose en el puerto 82.
<?php
$curl = curl_init();
$timeout = 30;
$ret = "";
$url="http://localhost:82/put_val?val=".$_GET["val"];
curl_setopt ($curl, CURLOPT_URL, $url);
curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($curl, CURLOPT_MAXREDIRS, 20);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5");
curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
$text = curl_exec($curl);
echo $text;
?>
Aquí está el javascript que realiza la llamada al archivo PHP
function getdata(obj1, obj2) {
var xmlhttp;
if (window.XMLHttpRequest)
xmlhttp=new XMLHttpRequest();
else
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","phpURLFile.php?eqp="+obj1+"&val="+obj2,true);
xmlhttp.send();
}
Mi HTML se ejecuta en WAMP en el puerto 80. Así que ahí vamos, se ha eludido la misma política de origen :-)
El JSONP viene a la mente:
JSONP o "JSON con relleno" es un complemento al formato de datos JSON base, un patrón de uso que permite que una página solicite y use JSON de manera más significativa desde un servidor que no sea el servidor primario. JSONP es una alternativa a un método más reciente llamado Intercambio de recursos de origen cruzado.
Esto analiza más o menos lo que está disponible: http://www.slideshare.net/SlexAxton/breaking-the-cross-domain-barrier
Para la solución postMessage eche un vistazo a:
https://github.com/chrissrogers/jquery-postmessage/blob/master/jquery.ba-postmessage.js
y una versión ligeramente diferente:
https://github.com/thomassturm/ender-postmessage/blob/master/ender-postmessage.js
La forma más reciente de superar la política de origen idéntico que he encontrado es http://anyorigin.com/
El sitio está hecho para que simplemente le des cualquier URL y genera código javascript / jquery para ti que te permite obtener los html / data, independientemente de su origen. En otras palabras, convierte cualquier url o página web en una solicitud JSONP.
Lo encontré bastante útil :)
Aquí hay algunos ejemplos de código javascript de anyorigin:
$.getJSON(''http://anyorigin.com/get?url=google.com&callback=?'', function(data){
$(''#output'').html(data.contents);
});
No puedo reclamar el crédito por esta imagen, pero coincide con todo lo que sé sobre este tema y ofrece un poco de humor al mismo tiempo.
Personalmente, window.postMessage
es la forma más confiable que he encontrado para los navegadores modernos. Tienes que hacer un poco más de trabajo para asegurarte de no estar abierto a los ataques XSS, pero es una compensación razonable.
También hay varios complementos para los populares kits de herramientas de Javascript que envuelven window.postMessage
que proporcionan una funcionalidad similar a los navegadores antiguos que usan los otros métodos mencionados anteriormente.
Yo uso JSONP.
Básicamente, agregas
<script src="http://..../someData.js?callback=some_func"/>
en tu pagina.
Se debe llamar a some_func () para que se le notifique que los datos están en.