Let me introduce my problem step by step:
I was using a socket connection on the address www.mydomain.com:1925 to provide a chat service for my users. When I moved to cloudflare, I could not connect to port 1925 directly because of the fact that my requests were reaching my origin server over cloudflare and the port was changing.
How did I solve it?
I created a subdomain chat.mydomain.com whose DNS settings point to my origin server not cloudflare. I bypassed cloudflare by this way and I connected my chat service by using chat.mydomain.com:1925 on the browser. So far so good.
Here is the problem.
I am also using Flash and AS3. It is the core of my game on the site. Chat is working on html and my game in flash is in some part of my website. In flash, I was sending scores of players using again a socket connection on www.mydomain.com:1925 by a different namespace.(Since swf's host and url's host matched, I didn't have any problem I think).Since I have changed the domain to chat.mydomain.com:1925, Flash started to request a crossdomain.xml on chat.mydomain.com:1925. There is a crossdomain.xml file on chat.mydomain.com however I cannot serve it from chat.mydomain.com:1925. Here is my code:
Security.loadPolicyFile("https://chat.mydomain.com/crossdomain.xml");
var urlLoader:URLLoader = new URLLoader ();
var url:String = "https://chat.mydomain.com:1925/socket.io/1/";
var request:URLRequest = new URLRequest(url);
request.method = URLRequestMethod.POST;
urlLoader.dataFormat = URLLoaderDataFormat.TEXT;
urlLoader.addEventListener(Event.COMPLETE, completeHandler);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
urlLoader.load(request);
Since flash cannot find crossdomain.xml by getting 404, the requests in my code do not work. How can I solve this problem?
I have solved the problem. The URLRequest was trying to connect https://chat.example.com:1925/socket.io/1/. Since the swf was on the domain https://www.example.com, the swf was asking for https://chat.example.com:1925/crossdomain.xml. The port did not understand the https since it was used for my websocket. So I could not find any way to call this request in the swf. Then, I came up with an idea that I can call this url outside of the swf. Since I needed only handshakeid, I called this function via javascript. After getting the response, I loaded my swf by giving the handshakeid as an argument. That has solved my problem. For ones who need to call a function like this dynamically, they can use ExternalInterface calls. I hope it helps.
Related
i'm setting up a local SWF file that has to display some JSON data retrieved from a remote web server in some dynamic text fields.
Code:
Security.allowDomain("api.yourserver.com");
var loader:URLLoader = new URLLoader();
var request:URLRequest = new URLRequest("http://api.yourserver.com/yourendpoint");
request.method = URLRequestMethod.GET;
request.contentType = "application/json";
loader.load(request);
loader.addEventListener(Event.COMPLETE, decodeJSON);
function decodeJSON(event:Event):void{
var loader:URLLoader = URLLoader(event.target);
var Info:Object = JSON.parse(loader.data);
cont.textfield1.text = Info.text.field1;
cont.textfield2.text = Info.text.field2;
cont.textfield3.text = Info.text.field3;
}
Control > Test - It works. When run standalone it doesn't. I get the 2028 error (sandbox violation).
What i tried:
The LoaderContext method explained here on StackOverflow but i get a 2124 error (Loaded file is an unknown type - seems like the Loader method can only be used with stuff like SWF or medias like JPG etc.);
Setting local playback as described always here on StackOverflow but it didn't help;
Setting up and exception in the Global Flash Player Trust directory as explained here but got the 2028 again;
Anyone who was able to overcome this and willing to explain how or at least pointing in the right direction?
Thanks in advance!
I think that your current published file has just assess to local files only and not network ones, that's why you got security #2028 error.
To avoid that, you can change the Local playback security for your published swf from the Publish Settings to Access network only :
If you still get security errors when testing locally ( like #2048 error ), take a look on my answer of this question to add your local swf file to the trusted locations ...
Hope that can help.
I created a media server with 'Adobe Media Server Starter 5' on localhost and I am able to connect to it via an AS3 AIR Application. I can see the connection from my Application called 'SimpleServer' in the 'Adobe Media Server Administration Console' and I get a positive feedback about the connection:
Accepted a connection from IP:127.0.0.1, referrer: app:/SimpleServer.swf, pageurl:
I neither get a compile time nor a runtime error when trying to create a new SharedObject, I get no feedback at all. I am using the following code:
var shared:SharedObject = SharedObject.getRemote("HelloWorld", "rtmp://localhost/SimpleServer");
shared.addEventListener(SyncEvent.SYNC, syncEventHandler);
shared.connect(nc);
The NetConnection is created as followed:
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
nc.connect("rtmp://localhost/SimpleServer");
nc.client = this;
I cannot see a SharedObject in 'View Applications' -> 'Shared Objects' and I get no feedback about the creation. It is like the object has never been created. I also tried to set properties on the SharedObject, with no effect:
shared.setProperty("test", false);
Is there a simple solution to this problem or do I have to configure advanced server stuff? Thank you in advance!
As Sunil asked in the comments, is syncEventHandler ever called when you run your code?
To partially answer your questions: No you don't need any specific server-side configuration to be able to retrieve a SharedObject on the client side. Simply make sure your connected to the server before performing any attempt at getting/connecting to a remote shared object.
See this answer for some more informations
Besides, a good practive when attempting to get a remote shared object is also to use the uri from your NetConnection instance:
var shared:SharedObject = SharedObject.getRemote("HelloWorld", nc.uri);
I have a small multiplayer Flash game in which you can display a player profile by clicking at his or her avatar:
const PROFILE_URL:String = 'http://myserver/user.php?id=';
try {
navigateToURL(new URLRequest(PROFILE_URL+id), '_blank');
} catch(e:Error) {
}
This works well, but now I'd like to extend the user.php, so that players can add comments about each other. For authorization I'd like to use HTTP cookies, passed from the game.swf to the user.php.
(I don't want use GET or POST here, because GET will have the auth. variables in the URL and players might occasionaly send that URL around or post it in my forum. And POST will ask to re-post the request when you reload).
My problem is that I can't find the way to set HTTP cookies through the navigateToURL() method. Please advise me
Regards,
Alex
You could first authenticate by logging in via a seperate call, for example login.php and that script would start a session. Then all other calls to the same domain would already have the session started and you could check authentication. No need to worry about cookies when PHP can do it for you.
Assuming that you already have the cookie value in your swf you should be able to use the URLRequestHeader together with the URLRequest as follows:
var header:URLRequestHeader = new URLRequestHeader("Cookie", "<the cookie>");
var request:URLRequest = new URLRequest("http://example.com/script.php");
request.requestHeader.push(header);
request.method = URLRequestMethod.POST;
navigateToURL(request, "_blank");
Under certain circumstances, the browser will send the cookie to the server if it has been already set even if you don't explicitly include it in the request. This depends on the browser and the version of the Flash Player. You might also need to adjust your crossdomain.xml file.
Also note that there might be security implications of passing around an unencrypted cookie token. See Firesheep.
I've recently started putting together a Facebook Connect AS3 app and retrieving objects and images through the Graph API.
Running anywhere but locally, I receive security errors of the form:
SecurityError: Error #2122: Security sandbox violation: Loader.content: xxxx cannot access http://photos-a.ak.fbcdn.net/xxxx.jpg
A policy file is required, but the checkPolicyFile flag was not set when this media was loaded.
If I add a line of the form:
Security.loadPolicyFile("ht_tp://photos-a.ak.fbcdn.net/crossdomain.xml");
-then I'm fine for that server, but it seems that there are any number of domains with the photos-[letter] format. I've added the one for each in the alphabet - which happily retrieves crossdomain files successfully - but it doesn't seem like a nice solution, and doesn't accommodate any new hosting setups Facebook may will implement in the future.
One thing I'd considered was retrieving the crossdomain policy file on a per image basis, capturing the domain from the image URL before making the image request. Unfortunately, at least via the Graph solution (and I haven't looked too closely at the others), their servers resolve the image url after the request is made, from something more generic like:
ht_tps://graph.facebook.com/[objectId]/picture?type=small&access_token=[accessToken]
Has anyone found a more dependable means of ensuring that images can be retrieved without security sandbox violations? Or do Facebook maintain a definitive list that developers need to keep an eye on?
Thanks!
Load the facebook crossdomains on the initial of your application as below;
Security.allowDomain("*");
Security.allowInsecureDomain("*");
Security.loadPolicyFile("http://graph.facebook.com/crossdomain.xml");
Security.loadPolicyFile("https://graph.facebook.com/crossdomain.xml");
Security.loadPolicyFile("http://profile.ak.fbcdn.net/crossdomain.xml");
Security.loadPolicyFile("https://profile.ak.fbcdn.net/crossdomain.xml");
Security.loadPolicyFile("http://profile.cc.fbcdn.net/crossdomain.xml");
Security.loadPolicyFile("https://profile.cc.fbcdn.net/crossdomain.xml");
Security.loadPolicyFile("http://fbcdn-profile-a.akamaihd.net/crossdomain.xml");
Security.loadPolicyFile("https://fbcdn-profile-a.akamaihd.net/crossdomain.xml");
Security.loadPolicyFile("http://fbcdn-sphotos-a.akamaihd.net/crossdomain.xml");
Security.loadPolicyFile("https://fbcdn-sphotos-a.akamaihd.net/crossdomain.xml");
and then whenever you want to load an image from facebook, set the checkPolicy flag to true using the Loader's LoaderContext as below;
var context:LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
context.checkPolicyFile = true;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadFacebookPhoto);
loader.load(new URLRequest(YOUR_FACEBOOK_PHOTO_URL),context);
private function onLoadFacebookPhoto(e:Event):void
{
addChild(Bitmap(LoaderInfo(e.target).content));
}
Ideally I would guess that you'd want Flash to get the policy file on its own, rather than triggering it with Security.loadPolicyFile. Have you tried simply setting the checkPolicyFile flag for your Loader's LoaderContext?
Alternately, I believe that when you use URLLoader instead of Loader, Flash will request a policy file automatically, so you could try that as well. The tricky thing is that if you use Loader, Flash will let you display what you've loaded even without a crossdomain policy, so it doesn't load one unless you tell it to. When you use URLLoader, the load itself is not allowed unless there's a policy file, so Flash gets it automatically.
I am trying to load an xml file from wikipedia into my flash movie.
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, tweetLoaded);
loader.load(new URLRequest("http://en.wikipedia.org/w/api.php?action=query&rvprop=content&format=xml&pageids="+subNum));
loader.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorFunction);
This works fine when the flash file is run locally but when I upload to my domain it does not seem to work. I have read elsewhere that the cross domain rule does not apply to XML files only to images and other media. Is this true? If not is there a work around so that I can load in XML files from domains other than the one the swf is hosted on?
thanks
EDIT:
Okay I am really confused, my program queries both Bing API and the media wiki API. The Bing api call works fine, I can retrieve the XML search results back from it fine. But the wikipedia call does not work (online). I have tried listening for the Security_Error on the wikipedia call but it does not fire.
Does anyone have any ideas? Losing it a bit.
Thanks so much for you help. In the end i used http://pipes.yahoo.com
I created a pipe that took in an ID number then spat out a JSON object with the title of the corresponding wikipedia page.
which you can use here http://pipes.yahoo.com/wikibyid
For anyone else doing this you need to make sure you access the pipe from the yahoo api URL
http://pipes.yahooapis.com/
as this domain has the crossdomain.xml file.
A workaround is setting up a proxy with some server side language, so your swf loads data from your domain. This proxy forwards the request to the real host and returns the response to the swf. From the flash side, this works transparently.
You could make your proxy more or less sofisticated, but it could be as simple as (in php):
echo file_get_contents($_GET['target_url']);
This is just to give you an idea, you might want to validate the target_url parameter.
Have your swf call this php script and pass target_url as a parameter. Something like this:
var url:String = "proxy.php";
var paramVal:String = encodeURIComponent("http://en.wikipedia.org/w/api.php?action=query&rvprop=content&format=xml&pageids="+subNum);
url += "?target_url=" + paramVal;
loader.load(new URLRequest(url));
Note that for php this will require allowing fopen for urls (similar permissions might be neccesary for other server side technologies). Also, keep in mind this will affect your server bandwith consumption.
PS
Bing works because they have a crossdomain policy file in place to allow access to swfs from other domains.
http://api.bing.net/crossdomain.xml
Wikipedia doesn't have a crossdomain policy file that grants you access from other domains, so you cannot connect directly from your swf.