Pregunta

EvernoteEl bookmarklet puede hacer esto, por lo tanto, la respuesta más votada no responde a esto a pesar de que la recompensa se destinará a ella (de manera no productiva).

Tengo que llamar al dominio A.com (que configura las cookies con http) desde el dominio B.com.Todo lo que hago en el dominio B.com es (javascript):

var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = "A.com/setCookie?cache=1231213123";
head.appendChild(script);

Esto configura la cookie en A.com en todos los navegadores que he probado, excepto Safari.Sorprendentemente, esto funciona en IE6, incluso sin los encabezados P3P.

¿Hay alguna forma de hacer que esto funcione en Safari?

¿Fue útil?

Solución

Desde el Safari Developer FAQ:

Safari se envía con una política de cookies conservadora que limita la escritura de cookies únicamente a las páginas elegidas ("a las que navegó") por el usuario.Esta política conservadora predeterminada puede confundir a los sitios basados ​​en marcos que intentan escribir cookies y fallan.

No he encontrado ninguna manera de solucionar esto.

Si sirve de algo, Chrome tampoco configura las cookies si usas el <script> método de agregar, pero si tienes un método oculto <img> con la misma fuente, Chrome funciona además del resto de navegadores (excepto, nuevamente, Safari)

Otros consejos

Método de trabajo 2014-2016:

Tienes que hacer window.open al dominio / asignar una cookie / cerrar la ventana emergente, el dominio ahora está seguro.

Publicación original @ PHP múltiples cookies no funcionan en iPad / navegador de iPhone

Hay un poco de maldad suponiendo que tengan flash instalado.

No estoy seguro de si aún funciona o no, pero Flash'es " Local Shared Objects " también conocido como Cookies Flash podría ayudarlo a circunnavegar las políticas del mismo dominio de Safari.

Tutorial local de objetos compartidos

Sin embargo, puede ser complicado de implementar, por decir lo menos.

Además, los LSO están saliendo a la luz como una pesadilla de seguridad:

Así que piense cuidadosamente antes de usarlos.

Una publicación en un <iframe> oculto puede permitirle eludir esta restricción en Safari - http: / /gist.github.com/586182 :

<?php
  header('P3P: CP=HONK');
  setcookie('test_cookie', '1', 0, '/');
?>
<div id="test_cookie" style="position: absolute; top: -10000px"></div>
<script>
  window.setTimeout(function() {
    if (document.cookie.indexOf('test_cookie=1') < 0) {
      var      
        name = 'test_cookie',
        div = document.getElementById(name),
        iframe = document.createElement('iframe'),
        form = document.createElement('form');

      iframe.name = name;
      iframe.src = 'javascript:false';
      div.appendChild(iframe);

      form.action = location.toString();
      form.method = 'POST';
      form.target = name;
      div.appendChild(form);

      form.submit();
    }
  }, 10);
</script>

Hay una solución adecuada para este trabajo en 2015. Digamos que hay un sitio web y.com que incluye iframe con el sitio x.com. El iframe de x.com quiere almacenar una cookie. Eso no está permitido por la política de Safari, sin embargo, y.com puede almacenarlo. Por lo tanto, y.com debe escuchar los mensajes de x.com y luego almacenar la cookie.

var _cookieEvMth = window.addEventListener ? "addEventListener" : "attachEvent";
var _cookieEvAction = window[_cookieEvMth];
var _cookieEv = _cookieEvMth == "attachEvent" ? "onmessage" : "message";
_cookieEvAction(_cookieEv, function(evt){
  if(evt.data.indexOf('cookieset')!=-1){
    var datack = evt.data.split('|');
    YOUR_CUSTOM_COOKIE_SAVE_METHOD(datack[1],datack[2],datack[3]);
  }
},false);

Cuando x.com necesita almacenar la cookie, debe publicar un mensaje en y.com:

window.parent.postMessage('cookieset|'+ckName+'|'+ckVal+'|'+days,'*');

También puede abrirse camino para publicar mensajes en el iframe si desea leer la cookie. O puede incluirlo como parámetro en la URL del iframe de x.com usando javascript:

iframe.setAttribute('url','x.com/?cookieval='+YOUR_COOKIE_GET_METHOD('cookiename'));

Una solución alternativa que se nos ocurrió en mi trabajo fue configurar la cookie a través de una ventana. open () - puede que no sea óptima para usted (ya que tendrá una ventana emergente de culo feo abierta), pero funcionó bien para nosotros Teníamos que tener una ventana emergente abierta de todos modos para la autenticación OAuth.

Entonces, la esencia de lo que hicimos fue:

  1. El usuario hace clic en un enlace de B.com
  2. La ventana emergente se abre en A.com/setCookie
  3. A.com establece su cookie y luego redirige a B.com en el lugar apropiado

Nuevamente, no es válido en todas las soluciones, pero funcionó en la nuestra. Espero que esto ayude.

Sé que esta pregunta es bastante antigua, pero esto me ayudó a resolver el problema de las cookies:

var cookieForm = document.createElement("form");
cookieForm.action = "A.com/setCookie?cache=1231213123";
cookieForm.method = "post";
document.body.appendChild(cookieForm);

cookieForm.submit();

La idea de publicar un formulario en una página que establece sus cookies.

* EDITAR * Se ha informado que esta solución alternativa está cerrada en WebKit.

Luca,

Ok, esta respuesta tiene dos años, pero ... puede configurar una cookie de un iframe si publica un formulario en un iframe oculto. Puede hacer esto creando un formulario:

<form id="myiframe" action="http://yourdomain.com" method="POST" target="iframe_target">

Luego, en Javascript, obtenga una referencia al formulario y llame a enviar:

document.getElementsByTagName('form')[0].submit();

Puede escuchar la carga del iframe, o puede hacer que su página de acción de iframe emita algún javascript que indique la carga. He probado esto en Safari y Chrome, y funciona.

Saludos.

Esto podría no funcionar para todos, pero me encontré con este problema porque estaba sirviendo una aplicación React desde un host diferente al API, y la solución que finalmente funcionó fue usar DNS:

Nuestro cliente estaba siendo atendido desde www.company-name.com y nuestra API estaba en company-name.herokuapp.com. Al hacer un registro de CNAME api.company-name.com - & Gt; company-name.herokuapp.com, y cuando nuestro cliente usó ese subdominio para las llamadas a la API, Safari dejó de considerarlo como " tercero " cookie.

Lo bueno es que hay muy poco código involucrado, y todo está usando cosas bien establecidas ... La desventaja es que necesitas algo de control / propiedad sobre el host de la API si vas a usar https; necesitan un certificado que es válido para el dominio del cliente, o los usuarios recibirán una advertencia de certificado, por lo que esto no funcionaría (al menos no para algo orientado al usuario final) si la API en cuestión no es suya o de un socio.

Tal vez cree pragmáticamente y haga clic en un enlace con un href="A.com/setCookie?cache=1231213123" y un atributo de destino que apunta a un iframe oculto.Eso puede omita la política de navegación del usuario de Safari para configurar cookies (no tengo Safari a mano para probar).

Hice una investigación exhaustiva sobre esto cuando intentaba implementar un sitio que usaba Windows Live ID, que dependía de la capacidad de poder configurar cookies de terceros para cerrar sesión. Simplemente ... no funcionó. Nada de lo que pudiéramos hacer funcionaría. El equipo de Live ID también realizó una investigación exhaustiva y su respuesta fue & Quot; no puede hacer que funcione & Quot ;.

Tenga en cuenta esta línea:

script.src = "A.com/setCookie?cache=1231213123";

No pude hacer que esto funcionara hasta que agregué http, es decir,

script.src = "http://A.com/setCookie?cache=1231213123";

Encontré una solución simple. Solo necesita configurar la cookie por primera vez para verificar si la solicitud proviene del mismo origen o no, si no es lo habitual, debe devolver al iframe un script que repita esta solicitud, que ya tiene permiso para asignar la cookie. Después de eso, puede hacer otra solicitud directamente a través de iframe accediendo a esta cookie. Esto me ayudó en mi sistema de seguimiento. Intenta, esto funciona bien.

Vale la pena señalar que esta restricción en Safari no se aplica a todos los subdominios. Entonces, si visita directamente sitea.com, puede establecer cookies desde el subdominio.sitea.com sin interacción directa del usuario (iframe / JavaScript).

Esto fue relevante para mi caso al desarrollar una API. Si sus visitantes llegan a mysite.com, y luego desea que JavaScript interactúe con su API, si la API está alojada en api.mysite.com, funcionará en Safari.

Coloque este JavaScript en la página que realiza solicitudes entre dominios, http://example1.com/index.html :

  <script>
  var gup = function(name, url) {
     if(!url) url = location.href;
     name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
     var regexS = "[\\?&]"+name+"=([^&#]*)";
     var regex = new RegExp( regexS );
     var results = regex.exec( url );
     return results == null ? null : results[1];
  }
  var isSafari = navigator.vendor && navigator.vendor.indexOf('Apple') > -1 && navigator.userAgent && !navigator.userAgent.match('CriOS');
  var n = gup("activated");
  if(isSafari && n == null) {
     //browser is Safari and cookies have not yet been activated
     var current_url = location.protocol + '//' + location.host + location.pathname;
     var query_string = '?callback=' + encodeURIComponent(current_url + '?activated=1');
     var new_url = 'http://example2.com/activate.php' + query_string;
     window.location.href = new_url;
  }
  //the rest of your code goes here, and you can now set cross-domain cookies on Safari
  </script>

Luego cree un archivo en el otro servidor, que necesita establecer cookies, http://example2.com/ enable.php :

  <?php
  if(isset($_GET['callback'])) {
     header('Location: '.$_GET['callback']);
     exit();
  } else {
     //in case callback param is not set, simply go back to previous page
     echo "<script>";
     echo "window.history.back();";
     echo "</script>";
     exit();
  }
  ?>

Así es como funciona:

  1. Cuando http://example1.com/index.html se visita por primera vez, se realiza una comprobación para ver si el navegador es Safari y si un parámetro GET del nombre " activado " no existe. Si se cumplen ambas condiciones (lo que sucederá en la primera visita para un navegador Safari), el navegador se redirige a http : //example2.com/activate.php con un parámetro GET, " callback " ;, que contiene la URL de llamada añadida con un " activado " parámetro.

  2. http://example2.com/activate.php simplemente redirige de nuevo a URL contenida en el parámetro GET, & Quot; callback & Quot ;.

  3. Cuando http: //example1.index.html ahora se golpea esta segunda vez después de ser redirigido a, el parámetro GET, " activado " ahora se establecerá, por lo que el condicional del paso 1 no se ejecutará, permitiendo así que el script continúe la ejecución.

Esto cumple el requisito de Safari de que el navegador visite el dominio de terceros al menos una vez para comenzar a configurar las cookies.

Pruebe algo como:

var w = window.open("A.com/setCookie?cache=1231213123");
w.close();

Puede pasar por alto la política de seguridad de safari.

¿No es el atributo de tipo que falta lo que te molesta? -)

<script type="text/javascript">
  var head = document.getElementsByTagName("head")[0];
  var script = document.createElement("script");
  script.setAttribute("type","text/javascript");
  script.src = "A.com/setCookie?cache=1231213123";
  head.appendChild(script);
</script>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top