Recipe 15.6 Loading Remote Content by Proxy
15.6.1 Problem
You want to load content into your Flash
movie from another domain and are prevented from doing so by
Flash's security sandbox.
15.6.2 Solution
Use a proxy script on the server to
overcome the domain restrictions.
15.6.3 Discussion
Flash's security sandbox
prevents
you from loading content into your Flash movies from other domains
indiscriminately. You can load .swf files,
JPEGs, and MP3s from the same domain (or subdomain), and you can also
load .swf files from a trusting domain. However,
if you need to load content that is not in the same domain, and it is
not a trusted .swf file, you have at least three
options:
Copy the content to the same domain. This is the simplest solution if
it is possible for you to implement. Create a DNS entry within your own domain such that the remote server
is mapped to a machine name within the same domain. For example, you
can create a DNS entry such that
www.remotedomain.com maps to
remotedomain.localdomain.com within your own
domain. This solution requires that you have administrator access and
DNS knowledge. Create and use a proxy script that downloads the remote content to
the local server (either in memory or to disk) on the fly and then
returns the local copy to the Flash movie.
Included in this recipe are instructions for creating proxy scripts
for ColdFusion, Perl, .NET, and PHP.
If you use ColdFusion, you can write a proxy script with just a few
lines of code. Be aware that for this to work, the
<cfcontent> tag must be enabled on the
server. Some web hosts disable this tag for security purposes. To
create a ColdFusion proxy script, complete the following steps:
Create a new CFML document
named getMyContent.cfm. Add the following code to the document: <!--- Make sure the code is single-threaded so that the requested content
from one client doesn't get sent to another by mistake. --->
<cflock timeout="10" type="exclusive">
<!--- Get the remote content and save it to the server --->
<cfhttp url="#URL.url#" method="get" path="#ExpandPath("./")#"></cfhttp>
<!--- Display the content that has been saved. Delete the file afterward. --->
<cfcontent file="#ExpandPath(GetFileFromPath(Url.url))#" deletefile="yes"
type="#cfhttp.mimetype#">
</cflock> Save the document and upload it to your server. Refer to the testing instructions at the end of this recipe,
following the alternative language implementations.
If Perl is your choice for server-side scripting, you can create a
proxy script by completing the following steps:
Create a new Perl script document named
getMyContent.cgi. Add the following code to the document: #!/usr/bin/perl
# Proxy for Flash to bypass sandbox security limitations
# Supports GET and POST CGI methods
# Arun Bhalla (bhalla@arun.groogroo.com) 2002.07.15
use CGI qw/-oldstyle_urls/;
use HTTP::Request::Common;
use LWP::UserAgent;
my $cgi = new CGI;
my $ua = new LWP::UserAgent;
my $location;
my $method;
if ($cgi->param( )) {
# extract the location (URL) and method values from the parameter list
$location = $cgi->param('location');
$method = $cgi->param('method');
$cgi->delete('location');
$cgi->delete('method');
}
$method = uc($method) || 'GET';
my $res;
if ($method eq 'GET') {
if ($location =~ /\?/) {
$location .= '&' . $cgi->query_string;
} else {
$location .= '?' . $cgi->query_string;
}
$req = HTTP::Request->new(GET => $location);
} elsif ($method eq 'POST') {
$req = HTTP::Request->new(POST => $location);
$req->content_type($cgi->content_type( ) ||
'application/x-www-form-urlencoded');
$req->content($cgi->query_string);
}
my $res = $ua->request($req);
print $res->headers_as_string, "\n", $res->content;( Save the document and upload it to your server. Refer to the testing instructions at the end of this recipe,
following the alternative language implementations.
If you are using ASP.NET, follow these steps:
Create a new ASPX document named
getMyContent.aspx. Add the following code to the document: <%@ Page Language="C#" %>
<%
// First, get the content from the remote domain.
System.Net.HttpWebRequest webRequest =
(System.Net.HttpWebRequest)System.Net.WebRequest.Create(
(string)Request.QueryString["url"]);
System.Net.HttpWebResponse webResponse =
(System.Net.HttpWebResponse)webRequest.GetResponse( );
System.IO.Stream inStream = webResponse.GetResponseStream( );
// Next, read the content into an array of bytes.
byte[] buffer = new byte[(int)webResponse.ContentLength];
inStream.Read(buffer, 0, (int)webResponse.ContentLength);
// Next, set the appropriate content type and write the data as binary output.
Response.ContentType = webResponse.ContentType;
Response.BinaryWrite(buffer);
// Finally, close everything that is still open.
inStream.Close( );
webResponse.Close( );
%> Save the document and upload it to your server. Refer to the testing instructions at the end of this recipe,
following the alternative language implementations.
If you are using PHP, follow these steps:
Create a new PHP document named getMyContent.php. Add the following code to the document: <?php
// Stop Script from Timing Out.
set_time_limit(0);
// Check for variable "url" in querystring.
if ($_GET['url']) {
$fp = fopen ($_GET['url'], "r");
$file = "";
while (!feof($fp)) {
// Read Target File in chunks of 4 KB (4096 bytes).
$file .= fgets($fp, 4096);
}
fclose($fp);
// Send File Data to Flash
echo $file;
}
?> See the following testing instructions.
To test the script in your chosen language, run it from a web
browser. Regardless of the language implementation, the script
expects a parameter named url that
specifies the location of the data to copy to the proxy server.
For example, if the CFML script is being served at
http://www.mydomain.com/getMyContent.cfm and the
content that you want to retrieve is at
http://www.remotedomain.com/sound.mp3, you can
test the script in the browser using:
- http://www.mydomain.com/getMyContent.cfm?url=http://www.remotedomain.com/sound.mp3
This should retrieve the MP3 and play it in the browser window (if
you have the appropriate player).
Similarly, you can test the Perl script in a browser using the
following URL syntax:
- http://www.mydomain.com/cgi-bin/getMyContent.cgi?url=http://www.remotedomain.com/sound.mp3.
You can test the ASP.NET script in a browser using the following URL
syntax:
- http://www.mydomain.com/getMyContent.aspx?url=http://www.remotedomain.com/sound.mp3.
You can test the PHP script in a browser using the following URL
syntax:
- http://www.mydomain.com/getMyContent.php?url=http://www.remotedomain.com/sound.mp3.
Regardless of which language implementation you choose, you use it in
the same manner. When you invoke the loadMovie(
) or loadSound( ) method from your
Flash movie, instead of passing the URL to the remote asset, pass the
URL to the proxy script that is running on the same domain and append
the URL of the remote asset as a query string. For example:
myMovieClip.loadMovie("http://localhost/getMyContent.aspx?
url=http://www.remotedomain.com/someSwf.swf");
When you use a proxy script, be aware that the content can take even
longer to load into the Player than it would if the content is loaded
directly. The reason is that the asset has to first download to the
proxy server, then to the Player.
15.6.4 See Also
Recipe 15.2, Recipe 15.4, and Recipe 17.4
|