Something I suppose I had never really tested thoroughly before having not had to deal too much with random application embeds in the wild is the issue with ExternalInterface.available not quite doing what you might expect. According to Adobe documentation, this property
Indicates whether this player is in a container that offers an external interface. If the external interface is available, this property is
true
; otherwise, it isfalse
.
This is usually fine, as long as your embed has allowScriptAccess defined to either “always” or “sameDomain” (when the embed lives on the same domain as the swf). In addition, when prescribing embed code for folks to use, one would normally provide the embed code with allowScriptAccess set to “always” if there was a need to use ExternalInterface. Unfortunately, the ExternalInterface.available property will return true in cases where the allowScriptAccess parameter is not set to allow access (such as on Facebook flash embeds, where it is always rewritten to “never”) or when an industrious embedder has removed all the seemingly extraneous parameters from the embed.
The solution for this scenario is to always use a try-catch statement to trap any errors that occur when trying to access the ExternalInterface, and deal with the error accordingly. This might look something like:
if (ExternalInterface.available) {
try {
ExternalInterface.addCallback("moo", onMoo);
} catch (error:SecurityError) {
trace("Error: " + error.toString());
}
} else {
trace("ExternalInterface is not available for this container.");
}
This is not super pretty, but this will ensure that the app doesn’t generate any unexpected behavior in the wild.