Настройка междоменных файлов cookie в Safari - PullRequest
55 голосов
/ 03 января 2009

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

Мне нужно позвонить домену A.com (который устанавливает куки с http) из домена B.com. Все, что я делаю на домене B.com (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.

Есть ли способ заставить это работать в Safari?

Ответы [ 18 ]

54 голосов
/ 28 января 2009

Из Safari Developer FAQ:

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

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

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

13 голосов
/ 18 февраля 2010

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

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

6 голосов
/ 17 ноября 2014

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

Вы должны сделать window.open для домена / назначить куки-файл / закрыть всплывающее окно, домен теперь находится в первом списке.

Оригинальный пост @ PHP-файлы cookie не работают в браузере iPad / iPhone

4 голосов
/ 04 февраля 2009

Есть некоторая злая уловка, если предположить, что у них установлена ​​вспышка.

Я не уверен, работает ли он по-прежнему или нет, но Flash'es "Local Shared Objects", также известный как Flash Cookies , может помочь вам обойти политики Safari в отношении одного домена.

Учебник по локальным общим объектам

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

Кроме того, ЛСО выходят на свет как кошмар безопасности:

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

3 голосов
/ 01 октября 2010

Пост в скрытом <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>
3 голосов
/ 12 июня 2015

В 2015 году для этой работы есть подходящий обходной путь. Скажем, есть сайт y.com, который включает iframe с сайтом x.com. Iframe x.com хочет сохранить куки. Это не разрешено политикой 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. Или вы можете включить его в качестве параметра в URL iframe x.com, используя javascript:

iframe.setAttribute('url','x.com/?cookieval='+YOUR_COOKIE_GET_METHOD('cookiename'));
2 голосов
/ 08 мая 2009

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

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

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

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

2 голосов
/ 27 июля 2010

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

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

cookieForm.submit();

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

1 голос
/ 05 ноября 2018

Это может не сработать для всех, но я столкнулся с этой проблемой, потому что я обслуживал React App с другого хоста, чем API, и решение, которое в конечном итоге сработало, заключалось в использовании DNS:

Наш клиент обслуживался с www.company-name.com, а наш API был на company-name.herokuapp.com. Сделав запись CNAME api.company-name.com -> company-name.herokuapp.com и предложив нашему клиенту использовать этот поддомен для вызовов API, Safari прекратил считать его «сторонним» печенье.

Достоинством является то, что задействовано очень мало кода, и все это использует хорошо зарекомендовавшие себя вещи ... Недостатком является то, что вам нужен некоторый контроль / владение хостом API, если вы собираетесь использовать https - им нужен сертификат действителен для клиентского домена, иначе пользователи получат предупреждение о сертификате, поэтому это не сработает (по крайней мере, для конечного пользователя), если рассматриваемый API не ваш или партнера.

1 голос
/ 26 января 2011

* EDIT * Обходной путь был закрыт в 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, и это работает.

Приветствие.

...