Настройка междоменных cookies в Safari

в Evernoteбукмарклет способен это сделать, поэтому самый популярный ответ не отвечает на это, даже если щедрость пойдет на это (непродуктивным образом).

Я должен вызвать домен A.com (который устанавливает куки с http) из домена B.com - ... Все, что я делаю на домене B.com is (javascript):

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

это устанавливает cookie на A.com в каждом браузере, который я тестировал, кроме Safari. Удивительно, что это работает в IE6, даже без Заголовки P3P.

есть ли способ сделать эту работу в IE?

17 ответов


С Safari Developer FAQ:

Safari поставляется с консервативной политикой cookie, которая ограничивает запись cookie только страницами, выбранными ("перемещенными") пользователем. Эта консервативная политика по умолчанию может запутать сайты на основе фреймов, которые пытаются писать куки и терпят неудачу.

Я не нашел способа обойти это.

Если это чего-то стоит, Chrome не устанавливает куки-файлы, если вы используете <script> метод добавления, но если у вас есть скрытый <img> С тем же источником Chrome работает в дополнение к остальным браузерам (кроме, опять же, Safari)


вот решение, которое работает:

http://anantgarg.com/2010/02/18/cross-domain-cookies-in-safari/


метод работы 2014-2016:

вы должны сделать окно.откройте для домена / назначение печенье / закрыть всплывающее окно, домен теперь safelisted.

Оригинальный пост @ PHP несколько куки не работает на iPad / iPhone браузер


есть немного злой трюк, предполагая, что у них установлена вспышка.

Я не уверен, что он все еще работает или нет, но Flash'ES "локальные общие объекты" ака Flash Cookies может помочь вам обойти политику одного домена Safari.

Локальный Общий Объект Учебник

однако это может быть сложно реализовать, мягко говоря.

Additonally, LSO приходят в свет как кошмар безопасности:

поэтому тщательно подумайте, прежде чем использовать их.


сообщение для скрытого <iframe> может позволить вам обойти это ограничение в 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>

есть правильное решение для этой работы в 2015 году. Допустим, есть сайт y.com который включает iframe с сайтом x.com - ... В x.com iframe хочет сохранить cookie. Однако это не разрешено политикой Safari, y.com способен хранить его. Так что ... y.com должен прослушивать сообщения от x.com а затем сохраните сам 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);

когда x.com необходимо сохранить cookie, он должен отправить сообщение y.com:

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

также вы можете работать свой путь к сообщению сообщение в iframe, если вы хотите прочитать файл cookie. Или вы можете включить его как параметр в x.com url iframe с использованием javascript:

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

обходной путь, который мы только что придумали на моей работе, состоял в том, чтобы установить cookie через окно.open () - это может быть не оптимально для вас (так как у вас будет открыто всплывающее окно с уродливой задницей), но для нас это сработало хорошо. Нам все равно пришлось открыть всплывающее окно для аутентификации OAuth.

Итак, суть того, что мы делали, было:

  1. пользователь щелкает ссылку из B.com
  2. всплывающее окно открывается на A.com/setCookie
  3. A.com устанавливает свой cookie, а затем перенаправляет на B.com в нужном месте

опять же, не во всех решениях, но он работал в нашем. Надеюсь, это поможет.


Я знаю, что этот вопрос довольно старый, но это помогло мне решить проблему cookies:

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

cookieForm.submit();

идея сделать сообщение формы на странице, которая устанавливает ваши куки.


*редактировать* Этот обходной путь был закрыт в WebKit.

Луки,

хорошо, так что этому ответу два года, но... вы можете установить cookie из iframe, если вы отправляете форму в скрытый iframe. Вы можете сделать это, создав форму:

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

затем в Javascript получите ссылку на форму и вызовите submit:

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

Вы можете слушать загрузку iframe, или вы можете иметь свой страница действия iframe выдает некоторый javascript, который сигнализирует о загрузке. Я тестировал это в Safari и Chrome, и он работает.

Ура.


возможно, прагматично создать и щелкнуть ссылку с href="A.com/setCookie?cache=1231213123" и целевой атрибут, указывающий на скрытый iframe. Это мая обход политики навигации пользователя Safari для установки файлов cookie(у меня нет Safari для тестирования.)


Я сделал некоторые обширные исследования вокруг этого, когда я пытался развернуть сайт, который использовал Windows Live ID, который зависел от возможности установить куки-файлы 3rd для выхода из системы. Это просто... не получилось. Мы ничего не могли сделать, чтобы это сработало. Команда Live ID также провела обширное расследование, и их ответ был "не может заставить его работать".


обратите внимание на эту строку:

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

Я не мог заставить это работать, пока я не добавил http, т. е.

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

Я нашел простое решение. Вам просто нужно в первый раз установить cookie, чтобы проверить, пришел ли запрос из того же источника или нет, если не как обычно, вам нужно вернуть в iframe скрипт, который повторит этот запрос, уже имея разрешение назначить cookie. После этого вы можете сделать другой запрос непосредственно через iframe доступ к этому cookie. Это помогло мне в моей системе слежения. Попробуйте, это работает хорошо.


стоит отметить, что это ограничение в Safari не применяется к поддоменам. Так если вы сразу посещаете sitea.com, затем вы можете установить cookies из subdomain.sitea.com без прямого взаимодействия с пользователем (iframe / JavaScript).

Это было актуально для моего случая при разработке API. Если вы гости прибывают в mysite.com, а затем вы хотите, чтобы какой-то JavaScript взаимодействовал с вашим API, а затем, если API размещен на api.mysite.com, тогда он будет работать на Safari.


поместите этот JavaScript на страницу с междоменными запросами,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>

затем создайте файл на другом сервере, который должен установить 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();
  }
  ?>

вот как это работает:

  1. когда http://example1.com/index.html сначала посещается, проверяется, является ли браузер Safari и является ли GET параметр с именем "активировано" не существует. Если оба условия выполнены (что произойдет при первом посещении браузера Safari), то браузер перенаправляется наhttp://example2.com/activate.php с параметром GET, "обратный вызов", содержащий URL-адрес вызова, добавленный с параметром" активирован".

  2. http://example2.com/activate.php просто перенаправляет обратно на URL, содержащийся в параметре GET, "обратный вызов".

  3. , когда http://example1.индекс.HTML-код теперь хит во второй раз после перенаправления-to, параметр GET, "активированный" теперь будет установлен, поэтому условное с шага 1 не будет выполняться, что позволит скрипту продолжить выполнение.

Это соответствует требованию Safari о том, чтобы браузер посещал сторонний домен по крайней мере один раз, чтобы начать установку куки.


попробуйте что-то вроде:

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

это может обойти политику безопасности safari.


это не отсутствующий атрибут типа, который вас раздражает ?-)

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