22

Cross-domain cookies/sessions in Safari and all other browsers

Want to read a simplified version of this article? Read my follow-up article regarding Google’s iPhone Tracking

The Problem

Safari does not allow cross-domain cookies. In other words, if on X.com, you load an iFrame with contents of Y.com and set a cookie in the iFrame, Safari will not save the cookie. This problem also occurs in IE6/7 but can be resolved by sending a P3P header.

The Solution

I am not entirely sure why this works, but the cookie gets saved if a post is made to the iFrame. This solution relies of jQuery but can be adapted to any other.

Here is the code that goes on the remote domain:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
<script>
var isSafari = (/Safari/.test(navigator.userAgent));
var firstTimeSession = 0;

function submitSessionForm() {
	if (firstTimeSession == 0) {
		firstTimeSession = 1;
		$("#sessionform").submit();
		setTimeout(processApplication(),2000);
  	}	
}

if (isSafari) {
	$("body").append('<iframe id="sessionframe" name="sessionframe" onload="submitSessionForm()" src="http://www.yourdomain.com/blank.php" style="display:none;"></iframe><form id="sessionform" enctype="application/x-www-form-urlencoded" action="http://www.yourdomain.com/startsession.php" target="sessionframe" action="post"></form>');
} else {
	processApplication();
}

function processApplication() {
	alert('Session has been set. Now you can start your application!');
}
</script>

The contents for startsession.php would be as simple as:

<?php
header('P3P: CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"'); 
session_start();

To make sure that your site is compatible with IE6/7, always output the following header:

<?php
header('P3P: CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"'); 

Unfortunately, there is no way to find out when the browser has completed submitting the form. Thus, I have placed a delay of 2 seconds. This form needs to be submitted only once per user session. Then you can set your session data in PHP and it will be picked up by your remote domain. You can adapt the same example if you want to set cookies instead of starting a PHP session.

Comments/Suggestions?
Do let me know your suggestions on how we can improve this code.

Spread The Word
If you like what you are reading, then please help spread the word by re-tweeting, blogging or using the ShareThis button below. Thank you.


349 Words
94497 Views