Question

Le bookmarklet d'Evernote est capable de le faire. Par conséquent, la réponse la plus votée ne répond pas, même si la prime ira à elle (de manière non productive).

Je dois appeler le domaine A.com (qui définit les cookies avec http) à partir du domaine B.com. Tout ce que je fais sur le domaine B.com est (javascript):

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

Ceci configure le cookie sur A.com sur tous les navigateurs que j'ai testés, à l'exception de Safari. Étonnamment, cela fonctionne dans IE6, même sans les en-têtes P3P.

Existe-t-il un moyen de faire fonctionner cela dans Safari?

Était-ce utile?

La solution

Extrait du Safari Developer FAQ :

  

Safari est livré avec une politique de cookie conservatrice qui limite les écritures de cookie aux seules pages sélectionnées (& "; navigué vers &") par l'utilisateur. Cette stratégie conservatrice par défaut peut confondre les sites basés sur des cadres qui tentent d’écrire des cookies et échouent.

Je n'ai trouvé aucun moyen de contourner ce problème.

Si cela vaut la peine, Chrome ne configure pas les cookies non plus si vous utilisez le <script > méthode d’ajout, mais si vous avez caché <img > avec la même source, Chrome fonctionne en plus du reste des navigateurs (sauf, à nouveau, Safari)

Autres conseils

Méthode de travail 2014-2016:

Vous devez faire window.open au domaine / assigner un cookie / fermer la popup, le domaine est maintenant sauvegardé.

Message original @ Plusieurs cookies PHP ne fonctionnent pas sur iPad / Navigateur iPhone

Il existe un truc diabolique en supposant que Flash est installé.

Je ne sais pas si cela fonctionne toujours ou non, mais Flash'es & "Objets partagés locaux &"; Les cookies Flash peuvent vous aider à faire le tour des stratégies de même domaine de Safari.

Didacticiel sur les objets partagés locaux

Cependant, sa mise en œuvre peut être compliquée, pour le moins.

De plus, les LSO deviennent un cauchemar pour la sécurité:

Alors réfléchissez bien avant de les utiliser.

Un message sur un <iframe> message caché peut vous permettre de contourner cette restriction dans 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>

Il existe une solution de contournement appropriée pour ce travail en 2015. Supposons qu'il existe un site Web y.com qui inclut iframe avec le site x.com. L'iframe x.com veut enregistrer un cookie. Cela n’est pas autorisé par la politique de Safari, cependant, y.com est capable de le stocker. Donc, y.com doit écouter les messages de x.com, puis stocker le cookie lui-même.

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);

Lorsque x.com doit stocker le cookie, il doit envoyer un message à y.com:

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

Si vous souhaitez lire le cookie, vous pouvez également poster votre message sur l'iframe. Ou vous pouvez l’inclure en tant que paramètre dans l’URL x.com iframe à l’aide de javascript:

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

Une solution de contournement que nous venons tout juste de trouver dans mon travail était de définir le cookie via une fenêtre.open () - ce n'est peut-être pas optimal pour vous (car vous aurez une fenêtre assoiffée d'âne ouverte), bien pour nous. Nous devions quand même ouvrir une fenêtre popup pour l’authentification OAuth.

Le but de ce que nous avons fait était donc:

  1. l'utilisateur clique sur un lien de B.com
  2. La fenêtre contextuelle s'ouvre sur A.com/setCookie
  3. A.com définit son cookie, puis redirige vers B.com au bon endroit

Encore une fois, non valable dans toutes les solutions, mais cela a fonctionné dans la nôtre. J'espère que cela vous aidera.

Je sais que cette question est plutôt ancienne, mais cela m'a aidé à résoudre le problème des cookies:

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

cookieForm.submit();

L'idée de publier un formulaire sur une page qui définit vos cookies.

* EDIT * Cette solution de contournement a été signalée fermée dans WebKit.

Luca,

Ok, cette réponse a donc deux ans, mais ... vous pouvez définir un cookie depuis un iframe si vous postez un formulaire dans un iframe masqué. Vous pouvez le faire en créant un formulaire:

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

Puis, en Javascript, obtenez une référence au formulaire et appelez submit:

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

Vous pouvez écouter le chargement de l’iframe ou laisser votre page d’action iframe émettre du code javascript qui signale la charge. J'ai testé cela dans Safari et Chrome, et cela fonctionne.

A bientôt.

Cela ne fonctionnera peut-être pas pour tout le monde, mais je suis tombé sur ce problème car je servais une application React à partir d'un hôte différent de celui de l'API et la solution qui a finalement fonctionné consistait à utiliser DNS:

Notre client était servi depuis www.company-name.com et notre API s'appelait company-name.herokuapp.com. En créant un CNAME enregistrement api.company-name.com - & Gt; company-name.herokuapp.com, et lorsque notre client a utilisé ce sous-domaine pour les appels d'API, Safari a cessé de considérer qu'il s'agit d'un & "tiers"!! " cookie.

L’inconvénient, c’est que très peu de code est impliqué et qu’il utilise des éléments bien établis ... L’inconvénient est que vous devez avoir un contrôle / un droit de propriété sur l’hôte de l’API pour pouvoir utiliser https. certificat valide pour le domaine client, sinon les utilisateurs recevront un avertissement de certificat - cela ne fonctionnera donc pas (du moins pas pour les utilisateurs finaux) si l'API en question n'est ni la vôtre ni celle d'un partenaire.

Peut-être créer et cliquer de manière pragmatique et cliquer sur un lien avec un attribut href="A.com/setCookie?cache=1231213123" et une cible pointant vers un iframe masqué. Cela peut contourner la politique de Safari de navigation des utilisateurs pour l’installation de cookies (je n’ai pas Safari à tester.)

J'ai effectué des recherches approfondies à ce sujet lorsque j'essayais de déployer un site utilisant Windows Live ID, ce qui dépendait de la possibilité de définir des cookies tiers afin de vous déconnecter. Cela n'a tout simplement pas fonctionné. Rien de ce que nous pourrions faire ne le ferait fonctionner. L’équipe Live ID a également mené une enquête approfondie et leur réponse a été & «Ne peut pas le faire fonctionner &«;

Notez cette ligne:

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

Je ne pouvais pas que cela fonctionne avant d’ajouter le http, c.-à-d.

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

J'ai trouvé une solution simple. Vous avez juste besoin d’un cookie initial pour vérifier si la demande provient de la même origine ou non, sinon, vous devez retourner dans iframe un script qui répètera cette demande, ayant déjà l’autorisation d’affecter un cookie. Après cela, vous pouvez faire une autre demande directement via iframe en accédant à ce cookie. Cela m'a aidé dans mon système de suivi. Essayez, cela fonctionne bien.

Il est intéressant de noter que cette restriction dans Safari ne s'applique pas aux sous-domaines. Donc, si vous visitez directement sitea.com, vous pouvez configurer les cookies de subdomain.sitea.com sans interaction directe de l'utilisateur (iframe / JavaScript).

Cela était pertinent pour mon cas lors du développement d'une API. Si vous êtes des visiteurs qui arrivent sur mysite.com et que vous souhaitez que du JavaScript interagisse avec votre API, si l'API est hébergée sur api.mysite.com, cela fonctionnera sous Safari.

Placez ce code JavaScript sur la page des requêtes inter-domaines, 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>

Créez ensuite un fichier sur l'autre serveur, qui doit définir des cookies, http://example2.com/ activate.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();
  }
  ?>

Voici comment cela fonctionne:

  1. lorsque http://example1.com/index.html est visité pour la première fois, une vérification est faite pour voir si le navigateur est Safari et si un paramètre GET du nom & "activé &"; n'existe pas. Si les deux conditions sont remplies (ce qui se produira lors de la première visite d'un navigateur Safari), le navigateur est alors redirigé vers http : //example2.com/activate.php avec un paramètre GET, & "; callback &" ;, contenant l'URL d'appel associée à un & "activé" & "; paramètre.

  2. http://example2.com/activate.php redirige simplement vers le URL contenue dans le paramètre GET, & Quot; callback & Quot ;.

  3. Lorsque http: //example1.index.html est maintenant affiché après avoir été redirigé vers, le paramètre GET, & "activé" & "; sera maintenant défini, de sorte que la condition de l'étape 1 ne sera pas exécutée, permettant ainsi au script de continuer l'exécution.

Cela répond à l'exigence de Safari selon laquelle le navigateur doit visiter le domaine tiers au moins une fois pour pouvoir commencer à installer des cookies.

Essayez quelque chose comme:

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

Cela pourrait contourner la politique de sécurité de safari.

Ce n'est pas l'attribut de type manquant qui vous gêne? -)

<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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top