For those looking for an example that actually works (like me for the last 2 hours).
Here is a list of requirements you must fulfill in order for ExternalInterface to work:
- Make sure to use document[movieID] for NON-IE browsers
- Make sure to use window[movieID] for IE browsers
- Make sure the OBJECT tag has a PARAM tag for allowScriptAccess="sameDomain" or allowScriptAccess="always"
- Make sure the EMBED tag has attribute for allowScriptAccess="sameDomain" or allowScriptAccess="always"
- Make sure the EMBED tag has the NAME attribute set (do NOT set an ID attribute here because it is not required and may cause more problems for you)
- Make sure the OBJECT tag has an ID attribute set (also, make sure it is NOT the same as the NAME attribute on the EMBED tag)
The following example is a client-side file reader. It allows us to access an XML file from the client-side without a round-trip to the server.
There is one special requirement for this particular solution to work:
The user must click on the Flash movie itself... the JavaScript can't tell the Flash to bring up the Open file dialog (Google Error #2176).
Here is the HTML/JavaScript:
<script type="text/javascript">
function callback(text) {
console.log(text);
}
function thisMovie(movieName) {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName + 'IE'];
} else {
return document[movieName];
}
}
function debugFlash(t) {
console.log("debugFlash: " + t);
}
function setupFlashUploader(o) {
var component = thisMovie("ClientUploader");
component.setCallbackMethod('callback');
component.resetFilters();
component.addFileFilter('Text Files', '*.txt');
}
</script>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" id="ClientUploaderIE"
codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,1,52,0"
width="100" height="22">
<param name="movie" value="client-uploader.swf" />
<param name="bgcolor" value="#ffffff" />
<param name="allowScriptAccess" value="always" />
<embed src="client-uploader.swf" quality="high" bgcolor="#ffffff"
width="100" height="22" align="middle" name="ClientUploader"
play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer">
</embed>
</object>
And here is the Flash ActionScript:
import flash.net.FileReference;
import flash.net.FileFilter;
var fileRef:FileReference = new FileReference();
var callback:String;
var selectFilters:Array = [ new FileFilter("All Files", "*.*") ];
fileRef.addEventListener(Event.COMPLETE, onFileLoaded);
fileRef.addEventListener(Event.SELECT, onFileSelected);
function setCallbackMethod(cb:String):void {
callback = cb;
}
function resetFilters():void {
selectFilters = new Array();
}
function addFileFilter(label:String, ext:String):void {
selectFilters.push(new FileFilter(label, ext));
}
btnUpload.addEventListener(MouseEvent.CLICK, onUploadFile);
function onUploadFile(e:Event):void {
ExternalInterface.call("setupFlashUploader", "");
ExternalInterface.call("debugFlash", "Loading file...");
try {
if (fileRef.browse(selectFilters)) {
ExternalInterface.call("debugFlash", "Selecting file...");
} else {
ExternalInterface.call("debugFlash", "NOT Selecting file...");
}
} catch (e:Error) {
ExternalInterface.call("debugFlash", e.toString());
}
}
function onFileLoaded(e:Event):void {
var textContent:String = fileRef.data.toString();
ExternalInterface.call(callback, textContent);
}
function onFileSelected(e:Event):void {
fileRef.load();
}
ExternalInterface.addCallback('setCallbackMethod', setCallbackMethod);
ExternalInterface.addCallback('resetFilters', resetFilters);
ExternalInterface.addCallback('addFileFilter', addFileFilter);