ActionScript 3 and cross-domain problem

One of the most typical problems when coding AS3 to, let’s say, read data from an external XML source, is the cross-domain problem. According to security policies, not an url outside the domain where the AS application is being executed can be read, and different subdomains (such as www.yourdomain.com and yourdomain.com) are considered as different ones.

If the external resources you are trying to use come from your own application in another domain / server that you manage, then it can be fixed by adding a cross-domain policy file. This file must be defined on the content source server, and your AS application has to explicitly declare this server as allowed.

?View Code ACTIONSCRIPT
1
2
Security.allowDomain("domainone.com");
Security.allowDomain("domaintwo.com");

 

But if this is not the case and the content source is on a different remote server like, for instance, when implementing an RSS news reader which grabs content from sources like online news sites, then this problem can be worked out with a PHP proxy file.

1
2
$url = $_GET['url'];
readfile($url);

 

Since PHP is not affected by this policy, all the RSS feeds would be read through this small script, by calling it like ‘proxy.php?url=http://rss.thedomain.com’. Being this file exactly on the same domain than the AS application, the cross-domain problem is solved.

However, I have also found an odd behavior regarding this proxy PHP file: it works perfectly when opening the SWF compiled application directly on the browser (http://yourdomain.com/app.swf), but not when it is loaded as a part of the HTML code (embedded into an HTML page like http://yourdomain.com/app.html).┬áThe SWF application just doesn’t find the file (but it is there!), despite it reads without any problem a test text file on the same folder. So it seems as if the question mark ‘?’ changed the way the SWF application looks for files or executes url addresses. I don’t have a reason for this yet, but I guess that it is related to the way the Flash plugin manages the security, by using different sandboxes for direct and embedded executions of the application.

The solution for this second collateral problem is passing the domain name as a parameter, so that the full path to the proxy file can be constructed inside the AS application.

?View Code HTML4STRICT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<html>
	<head>
		<style type="text/css">
			...
		</style>
		<script type="text/javascript">
			...
		</script>
	</head>
	<body>
		<div id="flash">
			<? $basepath = getBasePath() ?>
			<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/" width="960" height="610">
		    	<param name="allowScriptAccess" value="always" />
		    	<param name="movie" value="main.swf?basepath=<?=$basepath?>" />
		    	<param name="quality" value="high" />
		    	<param name="bgcolor" value="#ffffff" />
				<param name="basepath" value="<?=$basepath?>" />
				<embed src="main.swf?basepath=<?=$basepath?>" 
				    quality=high bgcolor=#FFFFFF width="960" height="610" name="main"
				    type="application/x-shockwave-flash" 
				    pluginspace="http://www.macromedia.com/go/getflashplayer">
				</embed>
			</object>
		</div>
	</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
function getBasePath()
{
	$path = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
	$aPath = split('/',$path);
	if ( eregi ( '\.php', $aPath[sizeof($aPath)-1] ) )
	{
		$aPath[sizeof($aPath)-1] = '';
	}
	$path = join('/',$aPath);
	return $path;
}
?>

 

?View Code ACTIONSCRIPT
1
var proxyPath:String = this.loaderInfo.parameters.basepath + 'proxy.php'; // proxy for cross-domain problems

 

In any case, these problems only arise in online mode, I have not had any issue while working from my development suite, so it is when moving to a production environment when the pain in the ass can show out. Finally, this is nothing new, but handy and interesting not to forget.

Leave a Reply

Your email address will not be published. Required fields are marked *