it-swarm.com.de

Festlegen von domänenübergreifenden Cookies in Safari

Evernote 's Bookmarklet ist dazu in der Lage, daher beantwortet die am häufigsten vorgelegte Antwort dies nicht, auch wenn die Prämie (nicht produktiv) dorthin geht.

Ich muss Domain A.com (die Cookies mit http setzt) ​​von Domain B.com anrufen Alles, was ich auf Domain B.com mache, ist (Javascript): 

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

Dies setzt den Cookie auf A.com in jedem Browser, den ich getestet habe, mit Ausnahme von Safari . Erstaunlicherweise funktioniert dies in IE6, auch ohne die P3P-Header.

Gibt es eine Möglichkeit, dies in Safari funktionieren zu lassen?

55
Luca Matteis

Aus dem Safari Developer FAQ :

Safari wird mit einer konservativen Cookie-Richtlinie geliefert, die das Schreiben von Cookies auf die vom Benutzer ausgewählten Seiten beschränkt ("navigiert zu"). Diese konservative Standardrichtlinie kann Frame-basierte Websites verwirren, die versuchen, Cookies zu schreiben, und schlagen fehl.

Ich habe keine Möglichkeit gefunden, dies zu umgehen.

Wenn es etwas wert ist, setzt Chrome die Cookies auch nicht, wenn Sie die App-Methode <script> verwenden. Wenn Sie jedoch einen versteckten <img> mit derselben Quelle haben, funktioniert Chrome zusätzlich zu den übrigen Browsern (außer Safari)

52
13
Alec Smart

Arbeitsmethode 2014-2016:

Sie müssen window.open für die Domäne öffnen/ein Cookie zuweisen/das Popup schließen, die Domäne ist jetzt in einer Sicherheitsliste aufgeführt. 

Ursprünglicher Beitrag @ PHP Mehrere Cookies funktionieren nicht auf dem iPad/iPhone-Browser.

6

Es gibt einen bösen Trick, vorausgesetzt, sie haben Flash installiert.

Ich bin mir nicht sicher, ob es noch funktioniert oder nicht, aber Flash'es "Local Shared Objects", auch Flash Cookies, kann Ihnen dabei helfen, die Richtlinien der gleichen Domäne von Safari zu umgehen. 

Tutorial für lokales gemeinsames Objekt

Es kann jedoch kompliziert sein, um es gelinde auszudrücken. 

Darüber hinaus treten LSOs als Sicherheitsalptraum ins Licht: 

Überlegen Sie sich also genau, bevor Sie sie verwenden. 

4
Kent Fredric

Es gibt eine richtige Lösung für diese Arbeit im Jahr 2015. Nehmen wir an, es gibt die Website y.com, die iframe mit der Site x.com enthält. Der x.com-iframe möchte einen Cookie speichern. Dies ist in der Safari-Richtlinie nicht zulässig. Y.com kann sie jedoch speichern. Y.com muss also Nachrichten von x.com abhören und dann den Cookie selbst speichern.

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

Wenn x.com das Cookie speichern muss, muss eine Nachricht an y.com gesendet werden:

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

Sie können auch daran arbeiten, Nachrichten an den Iframe zu senden, wenn Sie den Cookie lesen möchten. Oder Sie können es als Parameter in x.com iframe url mit Javascript einfügen:

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

Ein Beitrag an einen versteckten <iframe> kann Ihnen ermöglichen, diese Einschränkung in Safari zu umgehen - 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>
3
daaku

Ein Workaround, den wir gerade bei meinem Job gefunden haben, war das Setzen des Cookies über window.open () - es ist möglicherweise nicht optimal für Sie (da Sie ein hässliches Pop-Up-Fenster haben), aber es hat gut funktioniert . Für die OAuth-Authentifizierung musste ohnehin ein Popup-Fenster geöffnet sein.

Also war das Jist von dem, was wir getan haben:

  1. Benutzer klickt auf einen Link von B.com
  2. Das Popup-Fenster öffnet sich zu A.com/setCookie
  3. A.com setzt sein Cookie und leitet es an der richtigen Stelle an B.com weiter

Wiederum nicht in allen Lösungen gültig, aber es hat bei uns funktioniert. Hoffe das hilft.

2
umbrae

Ich weiß, dass diese Frage ziemlich alt ist, aber dies half mir, das Problem mit Cookies zu lösen:

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

cookieForm.submit();

Die Idee, ein Formular auf einer Seite zu veröffentlichen, auf der Ihre Cookies gesetzt werden.

2
ADOConnection

*EDIT * Diese Problemumgehung wurde in WebKit als geschlossen gemeldet.

Luca,

Ok, diese Antwort ist also zwei Jahre alt, aber ... Sie können einen Cookie aus einem Iframe setzen, wenn Sie ein Formular an einen verborgenen Iframe senden. Sie können dies tun, indem Sie ein Formular erstellen:

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

Dann holen Sie sich in Javascript einen Verweis auf das Formular und rufen Sie absenden auf:

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

Sie können sich das Onload von iframe anhören, oder Sie können auf Ihrer iframe-Aktionsseite Javascript anzeigen, das die Last signalisiert. Ich habe dies in Safari und Chrome getestet, und es funktioniert.

Prost.

1
thesmart

Ich habe diesbezüglich ausführliche Nachforschungen angestellt, als ich versuche, eine Website bereitzustellen, die Windows Live ID verwendet, die von der Möglichkeit abhängt, Cookies von Drittanbietern zum Abmelden zu setzen. Es hat einfach nicht funktioniert. Nichts, was wir tun könnten, würde es zum Laufen bringen. Das Live ID-Team führte auch umfangreiche Nachforschungen durch und ihre Antwort lautete: "Kann es nicht funktionieren lassen".

0
Brad Wilson

Beachten Sie diese Zeile:

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

Ich konnte dies nicht funktionieren lassen, bis ich das http hinzugefügt habe, d. H.

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

Dies funktioniert möglicherweise nicht für alle, aber ich bin auf dieses Problem gestoßen, weil ich eine React-App von einem anderen Host als der API aus bereitstelle. Die Lösung, die letztendlich funktioniert hat, war die Verwendung von DNS:

Unser Kunde wurde von www.company-name.com bedient und unsere API war auf company-name.herokuapp.com. Durch die Erstellung einesCNAMErecord api.company-name.com -> company-name.herokuapp.com und die Verwendung dieser Subdomäne durch unseren Client für API-Aufrufe hielt Safari ihn nicht mehr für einen "Drittanbieter". Plätzchen.

Der Vorteil ist, dass sehr wenig Code involviert ist und dass alles gut etablierte Dinge verwendet ... Der Nachteil ist, dass Sie etwas Kontrolle/Besitz des API-Hosts benötigen, wenn Sie https verwenden - sie benötigen ein gültiges Zertifikat für die Clientdomäne oder Benutzer erhalten eine Zertifikatswarnung - dies würde also nicht funktionieren (zumindest nicht für Endbenutzer), wenn die betreffende API nicht Ihrer oder der eines Partners gehört.

0
DrShaffopolis

Fügen Sie dieses JavaScript auf der Seite mit domänenübergreifenden Anforderungen ein, 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>

Erstellen Sie dann auf dem anderen Server eine Datei, die Cookies setzen muss, 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();
  }
  ?>

So funktioniert das: 

  1. Beim ersten Besuch von http://example1.com/index.html wird geprüft, ob der Browser Safari ist und ob ein GET-Parameter mit dem Namen "enabled" nicht vorhanden ist. Wenn beide Bedingungen erfüllt sind (was beim ersten Besuch eines Safari-Browsers der Fall ist), wird der Browser zu http://example2.com/activate.php mit dem GET-Parameter "callback" umgeleitet die aufrufende URL wurde mit einem "aktivierten" Parameter angehängt. 

  2. http://example2.com/activate.php führt einfach die URL zurück, die im GET-Parameter "callback" enthalten ist. 

  3. Wenn http: //example1.index.html nun dieses zweite Mal nach der Umleitung auf diesen Zieltreffer getroffen wird, wird jetzt der GET-Parameter "aktiviert" gesetzt, sodass die Bedingung von Schritt 1 nicht ausgeführt wird, was dies ermöglicht das Skript, um die Ausführung fortzusetzen.

Dies erfüllt die Anforderung von Safari, dass der Browser die Domäne eines Drittanbieters mindestens einmal besucht, um Cookies zu setzen.

0
Dane Iracleous

Es ist erwähnenswert, dass diese Einschränkung in Safari nicht für Subdomains gilt. Wenn Sie also direkt auf sitea.com gehen, können Sie Cookies von subdomain.sitea.com ohne direkte Benutzerinteraktion (iframe/JavaScript) setzen.

Dies war für meinen Fall bei der Entwicklung einer API relevant. Wenn Ihre Besucher bei mysite.com ankommen und Sie möchten, dass JavaScript mit Ihrer API interagiert. Wenn die API auf api.mysite.com gehostet wird, funktioniert sie auch auf Safari.

0
Dom

Vielleicht erstellen Sie pragmatisch einen Link mit einem href="A.com/setCookie?cache=1231213123" und einem Zielattribut, das auf einen verborgenen Iframe verweist. Das kann / die Safari-Richtlinie der Benutzernavigation zum Setzen von Cookies umgehen (ich habe Safari nicht zum Testen zur Verfügung.)

0
Zach

Ich habe eine einfache Lösung gefunden. Sie müssen zum ersten Mal ein Cookie setzen, um zu prüfen, ob die Anfrage aus demselben Ursprung stammt oder nicht. Wenn nicht wie üblich, müssen Sie ein Skript zurückgeben, das diese Anfrage wiederholt und bereits über die Berechtigung zum Zuweisen von Cookies verfügt. Danach können Sie andere Anfragen direkt über iframe ausführen, um auf dieses Cookie zuzugreifen. Das hat mir in meinem Trackingsystem geholfen. Versuchen Sie, das funktioniert gut.

0