Using a PHP Proxy with Flex to talk Cross Domain

Skill

Using a PHP Proxy with Flex to talk Cross Domain

Posted in:

Now one of the worst pieces of working with Flex is cross domain security, oh how I hate it sometimes. Now I understand that there is a reason that the Flash player can't just grab information from any domain it wants all willy nilly, but sometimes this really hampers getting something built. Silverlight also has this issue, and recently I went over using Yahoo Pipes for a proxy for a Silverlight Twitter Client. Today I am going to show how to build a simple PHP script to use as a cross domain proxy.

Below is a simple example application to show the working proxy script. The application has two buttons - one for attempting to pull my (Zwigby's) twitter rss feed directly from the twitter site and one to retrieve it using the PHP proxy. If there is an error a pop up will show with the error message. It is expected to show an error when not using the proxy, and when using the proxy the rss feed contents should show up in the text area below the buttons.

Get Adobe Flash player

Creating the PHP Proxy

The major piece of this tutorial is building the PHP script to act as a proxy for our cross domain requests. We are going to use cURL to make the request to the outside site. First and foremost is initializing cURL using curl_init(). We get the url to retrieve from the $_REQUEST variable url which in the Flex application I pass using POST. We also set a few other options, which can be seen in the code for the proxy below.

<?php
$ch = curl_init();
$timeout = 30;
$userAgent = $_SERVER['HTTP_USER_AGENT'];

curl_setopt($ch, CURLOPT_URL, $_REQUEST['url']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);

$response = curl_exec($ch);    

if (curl_errno($ch)) {
    echo curl_error($ch);
} else {
    curl_close($ch);
    echo $response;
}
?>

PHP cURL has many options but I just set ones I really needed. This includes the url (CURLOPT_URL), return transfer, (CURLOPT_RETURNTRANSFER), connection timeout (CURLOPT_CONNECTTIMEOUT), and the user agent (CURLOPT_USERAGENT). The url and connection timeout are pretty self explanatory but what is return transfer and user agent? Well the return transfer is actually a simple concept, it tells cURL to return the information requested as a string and not to output it directly. The user agent is a string that describes the browser and computer of the requester - this is important to make sure the information is returned in the correct format.

The final thing that needs to be done in the script is getting the response. This is done using the curl_exec() function which will execute the cURL session and return the response. Once the the session has been executed we can check for any errors and if there are none we close the session and echo out the response. That takes care of the PHP part of the sample.

Building the Flex

For this part of the tutorial I will explain how I sent the request to the proxy and to the normal twitter site. I am not going to go over all the inner details of building the interface or outputting the rss feed into the text area - all of these things are very typical of a flex application and we have plenty of Flex Tutorials here on the site. The requests are fairly simple also so here is the code and I will go over it afterward.

<mx:HTTPService id="noProxyService" method="GET" resultFormat="xml"
   url="http://twitter.com/statuses/user_timeline/13575682.rss"
   result="rssResults(event)" fault="rssFault(event)" />
<mx:HTTPService url="/files/proxy.php"
   id="proxyService" method="POST" resultFormat="xml"
   result="rssResults(event)" fault="rssFault(event)">
  <mx:request>
    <url>
      http://twitter.com/statuses/user_timeline/13575682.rss
    </url>
  </mx:request>
</mx:HTTPService>

Now those don't look too complicated now do they. The first HTTPService is the non-proxy one which is pretty evident from the url parameter being set to the twitter site. Some other items to notice - I ask for the result in xml because it is an xml rss feed - this makes it easier for me to output. I also have two events hooked up, the result and fault events which is where I display the error pop up or the output in the text area. The second HTTPService is slightly more complicated. It has its url parameter set to the PHP proxy file which we built earlier. The other difference is that we also have a request variable, <url>, which is passed using the POST method. The request variable is what I set to the Twitter RSS feed address. To send the requests we simply need to call either noProxyService.send() or proxyService.send() and that's it.

If anyone has any questions about the Flex or PHP code please feel free to leave a comment or send us an email. We are always more than happy to help out when time permits. Also you can look at the full source code for the Flex application if you would like.

Cricri
07/03/2008 - 09:15

I just had this really annoying problem today (I've a little few day experiment in flex ;), and used the same solution. But not with curl which seems more robust than my poor "fread()".

You just confirm me that's the only solution. Thanks.

reply

Lawrence
07/04/2008 - 02:06

What about for Java? Do you have knowledge how to do in say a Java Servlet as a proxy?

reply

Dragos
11/11/2008 - 05:01

For Lawrence

I think this will help you:
Proxy Servlet for AJAX requests to multiple, remote servers
http://technology.amis.nl/blog/999/proxy-servlet-for-ajax-requests-to-multiple-remote-servers

reply

Anonymous
03/01/2009 - 22:32

Ilike your comment box. I am going to copy it OK?

reply

The Fattest
03/01/2009 - 22:34

yeah that is fine go for it. the actual sliding comment box is default implementation of textarea from drupal.

reply

hannah
03/26/2009 - 16:42

yay i got it to work. thanks~

reply

Anonymous
07/19/2009 - 09:32

where do you place the proxy.php?

I have a flex app that resides inside a virtual directory on my localhost. lets say localhost/b is mapped to c:\b
my flex app sits inside c:\b\flexapp

where should i put my proxy.php? and how should i set the url to it from the code?

when i tried setting it to "../proxy.php" (it reisdes at c:\b\proxy.php) it works in debug, but when i create a release build it fails. the is "invoke failed"

reply

olivier
08/03/2009 - 22:04

it allright but what about multiple param in the request where do you put them ? im mean i suck at php ... :)

reply

olivier
08/03/2009 - 22:06

i think i guessed you put everything into you url ... every param

reply

The Fattest
08/04/2009 - 12:59

Yeah just drop all your params into the url.

reply

Authorizaton?
11/15/2009 - 10:26

So if I'm authenticated on two different sites a.com and b.com, and my SWF is hosted on b.com, and I use the proxy method to get data from a.com, don't I lose "REMOTE_USER" or other heade-based content when I use the proxy?

reply

LumberJack
01/21/2011 - 14:49

But what if your original URL has parameters

reply

Anonymous
01/24/2011 - 23:52

Work really good, thanks for the trick.

reply

Anonymous
03/20/2011 - 13:42

You said in the post "Now I understand that there is a reason that the Flash player can't just grab information from any domain it wants all willy nilly"

Can you please explain why Flash Player can't just grab information or can provide me some url where i can read about this.

reply

Anonymous
03/27/2011 - 00:02

Security error accessing url
Destination: DefaultHTTP

Security error accessing url
Unable to load WSDL. If currently online, please verify the URI and/or format of the WSDL

I have tried using crossdomain.xml every which way!

I'm using a auto-generated WSDL form within Flex 4. I have tested Flex 4 vs Flex 3 to see if Flash Player 10 security updates truly are to blame for the errors, but I still receive the errors within the Flex 3 auto-generated environment. The application and web service are fine when the application is run locally... but when the application runs on our server (and hits the web service on another server) I receive these errors.

This error:
Security error accessing url
Destination: DefaultHTTP

...occurs when attempting to use the proxy above!

This error:
Security error accessing url
Unable to load WSDL. If currently online, please verify the URI and/or format of the WSDL

...occurs when attempting to load WSDL as auto-generated within internal class.

I also have the following additional compiler arguments:
-locale en_US -use-network=true

Info on this is sparse, if anyone can shed some light it would be appreciated. Simply want the web service that works within browser, and within Flex app locally(tested on Flex 3.5 and Flex 4) to work when uploaded to server.

reply

Add Comment

Put code snippets inside language tags:
[language] [/language]

Examples:
[javascript] [/javascript]
[actionscript] [/actionscript]
[csharp] [/csharp]

See here for supported languages.

Javascript must be enabled to submit anonymous comments - or you can login.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.