web-dev-qa-db-ja.com

SafariでクロスドメインCookieを設定する

Evernote のブックマークレットはこれを行うことができます。したがって、最も賞賛された答えは、報奨金が(非生産的な方法で)行っても、これに答えません。 )。

ドメインB.comからドメインA.com(httpでCookieを設定)を呼び出す必要があります。ドメインB.comで行うことはすべて(javascript)です。

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

これにより、Safariを除く、テストしたすべてのブラウザーのA.comにCookieが設定されます。驚くべきことに、これはP3PヘッダーがなくてもIE6で機能します。

Safariでこれを動作させる方法はありますか?

57
Luca Matteis

から - Safari Developer FAQ

Safariには、Cookieの書き込みをユーザーが選択した(「ナビゲート先」)ページのみに制限する保守的なCookieポリシーが付属しています。このデフォルトの保守的なポリシーは、Cookieを書き込もうとして失敗するフレームベースのサイトを混乱させる可能性があります。

これを回避する方法は見つかりませんでした。

価値がある場合は、Chromeは<script>メソッドを追加しますが、非表示の<img>同じソースで、Chromeは残りのブラウザに加えて動作します(再び、Safariを除く)

55
13
Alec Smart

作業方法2014-2016:

ドメインに対してwindow.openを実行する/ Cookieを割り当てる/ポップアップを閉じる必要があります。これで、ドメインがセーフリストに登録されます。

元の投稿@ iPad/iPhoneブラウザーでPHPの複数のCookieが機能しない

6

フラッシュがインストールされていると仮定すると、少し悪意のあるトリックがあります。

それでも動作するかどうかはわかりませんが、Flashの「ローカル共有オブジェクト」別名Flash Cookiesは、Safariの同じドメインを迂回するのに役立ちます。ポリシー。

ローカル共有オブジェクトチュートリアル

ただし、控えめに言っても、実装が複雑になる場合があります。

さらに、LSOはセキュリティの悪夢であるとして光に近づいています。

したがって、それらを使用する前に慎重に検討してください。

4
Kent Fredric

2015年にこの作業を行うための適切な回避策があります。たとえば、サイトx.comにiframeを含むウェブサイトy.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,'*');

また、Cookieを読み取りたい場合は、iframeにメッセージを投稿する方法を使用できます。または、javascriptを使用してx.com iframe urlのパラメーターとして含めることができます。

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

非表示の<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
daaku

私の仕事で思いついた回避策は、window.open()を介してCookieを設定することでした-あなたにとって最適ではないかもしれません(あなたはいお尻のポップアップウィンドウが開いているので)が、私たちにとってはうまくいきました。とにかくOAuth認証のためにポップアップウィンドウを開く必要がありました。

だから私たちがやったことの要点は:

  1. ユーザーがB.comのリンクをクリックします
  2. A.com/setCookieのポップアップウィンドウが開きます
  3. A.comはCookieを設定し、適切な場所でB.comにリダイレクトします

繰り返しますが、すべてのソリューションで有効ではありませんが、私たちのソリューションでは機能しました。お役に立てれば。

2
umbrae

私はこの質問がかなり古いことを知っていますが、これはクッキーの問題を解決するのに役立ちました:

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

cookieForm.submit();

Cookieを設定するページにフォームを投稿するというアイデア。

2
ADOConnection

* [〜#〜] edit [〜#〜]*この回避策はWebKitでクローズされたと報告されています。

ルカ、

わかりましたので、この答えは2年ですが、...非表示のiframeにフォームを投稿すると、iframeからcookieを設定できます。これを行うには、フォームを作成します。

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

次に、JavaScriptでフォームへの参照を取得し、submitを呼び出します。

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

Iframeのオンロードをリッスンするか、iframeアクションページでロードを通知するjavascriptを発行することができます。これをSafariとChromeでテストしましたが、動作します。

乾杯。

1
thesmart

これは誰にとってもうまくいくとは限りませんが、APIとは異なるホストからReactアプリを提供していたため、この問題に遭遇しました。

クライアントはwww.company-name.comから提供され、APIはcompany-name.herokuapp.comにありました。 [〜#〜] cname [〜#〜] record api.company-name.com-> company-name.herokuapp.comを作成し、クライアントにそのサブドメインをAPI呼び出しに使用させる、Safariはそれを「サードパーティ」のCookieと見なすことをやめました。

欠点は、コードがほとんど関与せず、すべてが十分に確立されたものを使用していることです...欠点は、httpsを使用する場合、APIホストの制御/所有権が必要なことです-有効な証明書が必要ですクライアントドメインの場合、または証明書の警告がユーザーに表示されます。そのため、問題のAPIが自分のものでもパートナーのものでもない場合、これは機能しません(少なくともエンドユーザー向けのものでは機能しません)。

1
DrShaffopolis

ログアウトするためにサードパーティのCookieを設定できるかどうかに依存する、Windows Live IDを使用するサイトを展開しようとしたときに、これについていくつかの広範な調査を行いました。ただ…うまくいきませんでした。できることは何もありません。 Live IDチームも大規模な調査を行い、彼らの答えは「機能しません」でした。

0
Brad Wilson

次の行に注意してください。

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

Httpを追加するまでこれを機能させることはできませんでした。

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

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

次に、他のサーバーにファイルを作成します。このサーバーは、Cookieを設定する必要があります 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パラメーター「callback 」、「アクティブ化された」パラメータが追加された呼び出しURLを含む。

  2. http://example2.com/activate.php は、単にGETパラメーター「callback」に含まれるURLにリダイレクトします。

  3. http://example1.index.html がリダイレクト後2回目にヒットすると、GETパラメーターの「アクティブ化」が設定されるため、ステップ1の条件は実行されません。 、したがって、スクリプトの実行を継続できます。

これは、Cookieの設定を開始するために、ブラウザが少なくとも1回はサードパーティドメインにアクセスするというSafariの要件を満たします。

0
Dane Iracleous

Safariのこの制限はサブドメインには適用されないことに注意してください。したがって、sitea.comに直接アクセスすると、直接的なユーザー操作(iframe/JavaScript)なしでsubdomain.sitea.comからCookieを設定できます。

これは、APIを開発するときの私の事例に関連していました。訪問者がmysite.comにアクセスしていて、JavaScriptでAPIとやり取りしたい場合、APIがapi.mysite.comでホストされている場合、Safariで動作します。

0
Dom

おそらく、href="A.com/setCookie?cache=1231213123"および非表示のiframeを指すターゲット属性。 may Cookieを設定するためのSafariのユーザーナビゲーションポリシーをバイパスします(テストするのに便利なSafariはありません。)

0
Zach

簡単な解決策を見つけました。リクエストを同じOriginから送信するかどうかを確認するために、初めてcookieを設定する必要があります。通常ではない場合、このリクエストを繰り返すスクリプトをiframeに戻す必要があります。その後、このCookieにアクセスするiframeを介して他のリクエストを直接行うことができます。これは私の追跡システムに役立ちました。試してください、これはうまく機能します。

0