19

Safari on a Mac has a Block cookies set to From third parties and advertisers by default.

It stops the SharedObject from working if the embedded swf is from a different domain.

This problem isn't new: Safari 3rd party cookie iframe trick no longer working?

Has anyone found a solution (other then passing the Session ID through GET/POST params in each request)?

NOTE: I have no access to the site, which is embedding the swf, so there is no way to alter that HTML or to put any JavaScript, etc.

Community
  • 1
  • 1
sanchez
  • 4,519
  • 3
  • 23
  • 53

6 Answers6

12
function setCookie(){
   if ( navigator.userAgent.indexOf('Safari') != -1 &&
        navigator.userAgent.indexOf('Chrome') == -1 ){
      window.open('safari.php','','width=200,height=100' );
   }
}

// then we set the cookie in safari.php

Source: http://www.reizbombardement.de/archives/safari-5-1-4-enforces-cookie-policy

//UPDATE 23 July 2013

This crappy way of fixing this issue used to work until Safari 6.

Please see @Fabio Antunes and @ncubica comments below.

//UPDATE 23 July 2013 by Fabio Antunes

Here's my code

On the landing page we'll have a brief description about the app and a button saying something like "enter". I'm using jquery to simplify this process, creating a listener for the click event, I'll just put the javascript code, since I'm assuming you already have the rest of the html code for the landing page:

$(document).on("click", "#bt-landing", function(){
var left = (screen.width/2)-(500/2);
            var top = (screen.height/2)-(250/2);
            window.open('URL_FOR_THE_PHP_THAT_WILL_CREATE_THE_SESSION', '_blank', 'width=500,height=250,toolbar=0,location=0,menubar=0, top='+top+', left='+left);
});

This you'll open a small window, with 500 by 250 px, centered on your screen.

The code I have for the small window is this:

<?php setcookie("safari_cookie", "1");?>
    <html>
        <head>
            <meta charset="utf-8">
            <title>THE NAME OF YOUR APP OR SOMETHING THAT THE USER WE'LL READ AND ASSUME THAT THIS SMALL WINDOW IS RELIABLE</title>
        </head>
        <body>
        <script type="text/javascript">
        $(document).ready(function(){
           setTimeout(function(){window.close()},1000);
        })
        </script>
        </body>
    </html
Fabio Antunes
  • 22,251
  • 15
  • 81
  • 96
sanchez
  • 4,519
  • 3
  • 23
  • 53
  • 1
    Won't this trigger the popup blocker because user did not click to initiate this? In addition you are opening a new window that will have nothing in it, to me this seems not an acceptable production solution. – Abadaba Aug 09 '12 at 20:08
  • 1
    Currently, this is the _only_ way I could make things work reliably. Very bad work-around because Safari also has the "pop-up windows" blocked. @Abadaba if you come across a better solution, please share. FYI: Facebook Apps – wenbert Aug 09 '12 at 22:54
  • 1
    Thanks, I got rid of my same problem :) – Vardan Gupta Nov 28 '12 at 10:54
  • Problem still persisting for Safari 6.0.5 on mac, how we can tackle it? – Vardan Gupta Jul 15 '13 at 06:47
  • I've used this method, whenever the browser is safari I present a landing page with a button that says "enter" when the user presses it the pop window shows, since the user clicked on the button it's ok, won't be blocked. This pop up window will set the cookie and closes by itself after a few seconds – Fabio Antunes Jul 16 '13 at 11:05
  • you can create and append an hidden form with a target "_blank" to do the post and the user will never know... then close the window and return the control to the parent – ncubica Jul 18 '13 at 04:55
  • 1
    I added some code, that explains briefly the way I use to avoid this small obstacle – Fabio Antunes Jul 23 '13 at 16:57
11

Safari does still block cookies from domains which it has not visited in the top window.

To workaround this, we count($_COOKIES) in PHP and direct the browser to a page on our domain whose job it is to simply send the browser back to where it came from. It's a dirty trick which means some users will unnecessarily get moved away and then back, but then, the web is full of dirty tricks.

If you cannot set top.location.href to a page on the domain which needs to set cookies, or you cannot alter a page on said domain, then I can confidently say you'll need to use URL-based sessions.

However, an alternative option (which still requires being able to create a page on the domain) is to request that the user clicks on your SWF, you can then trigger window.open and have the URL point to the page you created. All it needs to do is load successfully, then the user (or even JS on the popup page itself) can close the popup. You may then set cookies.


I develop Facebook apps, which live inside iframes, which suffer this problem. Every single app has to be shipped with this fix.

rcambrj
  • 592
  • 3
  • 8
1

I can say from very recent experience that this is not a problem with Safari on a Mac, nor have I ever experienced it as a problem.

You mentioned the setting is blocking cookies from 3rd parties: SharedObject storage is never from a third party, it's from the site you're visiting (the 1st party?). So I don't think that will ever be an issue.

Using the Flash Player settings panel, the user can disable the SharedObject (or limit the amount of storage space). So in general, your app should handle the case where the SharedObject is not available.

However, I think most users are not aware of the SharedObject and that they can disable it.

Sunil D.
  • 17,983
  • 6
  • 53
  • 65
  • I have just set the setting to Block Third party cookies ( Win7 Safari ) and SharedObject is not working as it should. I will get some traces and update this post soon. – sanchez Jul 24 '12 at 17:16
  • Interesting... that setting is not the default, though right? Also, another thing that will block access to the shared object is "private" or "incognito" browsing (where the browser keeps cookies only for that particular session). Chrome has an option for doing this. – Sunil D. Jul 24 '12 at 18:20
  • 1
    I should have checked this in my own browser (Safari 5.1.7, Mac): In the Preferences, on the Privacy tab, the "Block cookies" setting is set to block cookies "from 3rd parties and advertisers". This is the default value (I don't think I've ever changed it). But in my case, accessing the SharedObject works just fine when blocking 3rd party cookies. – Sunil D. Jul 24 '12 at 18:25
  • 1
    Yes, editing the question/topic is not a bad idea. It sounds like your alternate idea (to persist data through cookies) won't work either. The only other options coming to mind are to persist the data on a server, or detect the problem in code and inform the user the data cannot be saved. – Sunil D. Jul 24 '12 at 20:26
1

You may need to use a cross-domain policy file for the swf to work correctly.

http://kb2.adobe.com/cps/142/tn_14213.html

Hades
  • 1,975
  • 1
  • 23
  • 39
1

I've solved in this way, but it's better to use HTML5 localstorage and make webservices restful because holding session variables in server2 make your application not well scalable. Here the code i've used to solve the 3rd party cookie problem. Basically guests of server1 goes first to server2 in order to take "the coin :D" and suddenly he come back to server1. In this way session variables of server2 are avaliable in all navigation. www.yourserver.com/index.html page

<script src="js/jquery.cookie.js" type="text/javascript"></script>
<script src="js/mobile-detect.js" type="text/javascript"></script>
<script>
var md = new MobileDetect(window.navigator.userAgent);
if (md.userAgent()=='Safari') {
    var firstsafariuser = $.cookie('safari-user');
    if (firstsafariuser != 'true') {
        $.cookie('safari-user', true);
        location.href='http://www.yourserver2.com/coin.php?frompage='
        +location.href.replace(location.hash,"")+'&hashtags='+location.hash.substr(1);
    }
}
</script>

www.yourserver2.com/coin.php

<?php
session_start(); 
if (isset($_GET["frompage"])&&$_GET["frompage"]!=null){
    $url=$_GET["frompage"];
} else {
    $url='http://www.yourserver.com';
}
if (isset($_GET["hashtags"])&&$_GET["hashtags"]!=null){
    $hash='#'.$_GET["hashtags"];
} else {
    $hash='';
}
header('Location:'.$url.$hash);
?>

P.S. window.open are seen like a kind of popup so you might have problem with ad-blockers or browser settings.

Marcello Kad
  • 186
  • 1
  • 7
0

Just to add a cleaner way without setTimeout and or jquery for the safari.xxx page. Works fine with the latest ios (8.1.2), I know for 8.1.0 there was a bug where the window/tab wouldn't close.

Here is the code:

<%
request.getSession(true); //or anyway to set the cookie depending on your language (jsp here)
%>

<script type="text/javascript">
    window.addEventListener("load", window.close);
</script>

The popup is not an issue in my case since it is initiated by a click from the user.

Kim D.
  • 806
  • 10
  • 15