Just wanted to leave a simple working solution here that does not require user interaction.
As I stated in a post I made:
Basically all you need to do is load your page on top.location, create the session and redirect it back to facebook.
Add this code in the top of your index.php
and set $page_url
to your application final tab/app URL and you’ll see your application will work without any problem.
<?php
// START SAFARI SESSION FIX
session_start();
$page_url = "http://www.facebook.com/pages/.../...?sk=app_...";
if (isset($_GET["start_session"]))
die(header("Location:" . $page_url));
if (!isset($_GET["sid"]))
die(header("Location:?sid=" . session_id()));
$sid = session_id();
if (empty($sid) || $_GET["sid"] != $sid):
?>
<script>
top.window.location="?start_session=true";
</script>
<?php
endif;
// END SAFARI SESSION FIX
?>
Note: This was made for facebook, but it would actually work within any other similar situations.
Edit 20-Dec-2012 – Maintaining Signed Request:
The above code does not maintain the requests post data, and you would loose the signed_request, if your application relies on signed request feel free to try the following code:
Note: This is still being tested properly and may be less stable than the first version.
Use at your own risk / Feedback is appreciated.
(Thanks to CBroe for pointing me into the right direction here allowing to improve the solution)
// Start Session Fix
session_start();
$page_url = "http://www.facebook.com/pages/.../...?sk=app_...";
if (isset($_GET["start_session"]))
die(header("Location:" . $page_url));
$sid = session_id();
if (!isset($_GET["sid"]))
{
if(isset($_POST["signed_request"]))
$_SESSION["signed_request"] = $_POST["signed_request"];
die(header("Location:?sid=" . $sid));
}
if (empty($sid) || $_GET["sid"] != $sid)
die('<script>top.window.location="?start_session=true";</script>');
// End Session Fix