- Apr 12, 2010 | 3 comment(s)
- Posted in: Flash
Loading an external swf with parameters in the URL
Recently I needed to load an external swf with parameters in the URL (eg. file.swf?foo=bar). The reason was to prevent loading of any cached version of the swf by adding a random number to the url. Seems like a simple enough task, right? Well it kind of is. But not as simple as just using the Loader class which throws a 2035: URL Not Found error. And using URLLoader also doesn’t work, as that throws a 2032: Stream Error. The only solution I could work out was to change the dataFormat property of the URLLoader to “binary” (it is set to “text” by default) load the swf, and then use a Loader’s loadBytes method to load the URLLoader’s data. See my ParamSWFLoader class below as well a simple usage example. Feel free to use it in your own projects. Note it makes us of Robert Penner’s AS3 Signals which you’ll need to download.
/**
*
* ParamSWFLoader class
*
* Copyright (c) 2010 Ben Kanizay
* This software is released under the MIT License
*
*/
package beekay.core.utils {
import org.osflash.signals.Signal;
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.events.ErrorEvent;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
/**
* @author ben.kanizay
*/
public class ParamSWFLoader {
protected var request:URLRequest;
protected var urlLoader:URLLoader;
protected var bytesLoader:Loader;
protected var _loadedContent:DisplayObject;
public function get loadedContent() : DisplayObject {
return _loadedContent;
}
public var signalError:Signal;
public var signalProgress:Signal;
public var signalComplete:Signal;
public function ParamSWFLoader() {
this.signalError = new Signal(String);
this.signalProgress = new Signal(int);
this.signalComplete = new Signal();
}
public function load(url:String) : void {
this.urlLoader = new URLLoader();
this.urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
this.request = new URLRequest(url);
this.urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.onLoaderSecurityError, false, 0, true);
this.urlLoader.addEventListener(IOErrorEvent.IO_ERROR, this.onLoaderIOError, false, 0, true);
this.urlLoader.addEventListener(ErrorEvent.ERROR, this.onLoaderError, false, 0, true);
this.urlLoader.addEventListener(ProgressEvent.PROGRESS, this.onURLLoaderProgress, false, 0, true);
this.urlLoader.addEventListener(Event.COMPLETE, this.onURLLoaderComplete, false, 0, true);
try {
this.urlLoader.load(this.request);
}
catch (error:Error) {
this.signalError.dispatch(error.message);
this.removeURLLoaderListeners();
}
}
protected function onLoaderError(event : ErrorEvent) : void {
this.signalError.dispatch(event.text);
this.removeURLLoaderListeners();
}
protected function onLoaderSecurityError(event : SecurityErrorEvent) : void {
this.signalError.dispatch(event.text);
this.removeURLLoaderListeners();
}
protected function onLoaderIOError(event : IOErrorEvent) : void {
this.signalError.dispatch(event.text);
this.removeURLLoaderListeners();
}
protected function onURLLoaderProgress(event : ProgressEvent) : void {
var percentLoaded:int = Math.round((event.bytesLoaded/event.bytesTotal)*100);
this.signalProgress.dispatch(percentLoaded);
}
public function removeURLLoaderListeners() : void {
this.urlLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, this.onLoaderSecurityError);
this.urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, this.onLoaderIOError);
this.urlLoader.removeEventListener(ErrorEvent.ERROR, this.onLoaderError);
this.urlLoader.removeEventListener(ProgressEvent.PROGRESS, this.onURLLoaderProgress);
this.urlLoader.removeEventListener(Event.COMPLETE, this.onURLLoaderComplete);
}
protected function onURLLoaderComplete(event : Event) : void {
this.removeURLLoaderListeners();
this.bytesLoader = new Loader();
this.bytesLoader.contentLoaderInfo.addEventListener(ErrorEvent.ERROR, this.onLoaderError, false, 0, true);
this.bytesLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.onBytesLoaderComplete, false, 0, true);
try {
this.bytesLoader.loadBytes(this.urlLoader.data);
}
catch (error:Error) {
this.signalError.dispatch(error.message);
this.removeBytesLoaderListeners();
}
}
protected function onBytesLoaderComplete(event : Event) : void {
this.removeBytesLoaderListeners();
this._loadedContent = this.bytesLoader.content;
this.signalComplete.dispatch();
}
public function removeBytesLoaderListeners() : void {
this.bytesLoader.contentLoaderInfo.removeEventListener(ErrorEvent.ERROR, this.onLoaderError);
this.bytesLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, this.onBytesLoaderComplete);
}
}
}
And a simple usage example:
package {
import beekay.core.utils.ParamSWFLoader;
import flash.display.Sprite;
/**
* @author ben.kanizay
*/
public class Main extends Sprite {
protected var swfLoader:ParamSWFLoader;
public function Main() {
this.swfLoader = new ParamSWFLoader();
this.swfLoader.signalError.addOnce(this.onSwfLoaderError);
this.swfLoader.signalProgress.add(this.onSwfLoaderProgress);
this.swfLoader.signalComplete.addOnce(this.onSwfLoaderComplete);
this.swfLoader.load("http://path/to/content.swf?cacheBlocker=" + parseInt(String(Math.random()*1000)));
}
protected function onSwfLoaderError(error:String) : void {
trace("ERROR: " + error);
}
protected function onSwfLoaderProgress(percent:int) : void {
trace(percent + "% LOADED");
}
protected function onSwfLoaderComplete() : void {
trace("DONE!");
this.swfLoader.signalProgress.remove(this.onSwfLoaderProgress);
this.addChild(this.swfLoader.loadedContent);
}
}
}
- Tweet this post (will automatically use the short url below)
- Short url for this post: http://bit.ly/9005L8
Ben Kanizay
hmm,useful information.. I have learned it LOL
Hey Ben,
You should be able to just use the data property of the URLRequest object to do this. Mind you, I haven’t tested in a live environment to see if cache bypassing works, but in theory it should.
—–
var params:URLVariables = new URLVariables();
params.noCache = Math.random();
var request:URLRequest = new URLRequest(”http://localhost/redshift/data/swf/game.swf”);
request.data = params;
request.method = URLRequestMethod.GET;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(request);
function onLoadComplete (e:Event) : void
{
trace(”Load complete”);
var p:Object = loader.contentLoaderInfo.parameters;
for (var i:String in p)
trace(i, “=”, p[i]); // output: noCache = 0.8092844560742378
}
Cheers Stephen. Haven’t tried that way for cache bypass. Might give it a run and see.