views:

8085

answers:

4

I am trying to enable communication between Javascript and Flash via ExternalInterface across domains. The Javascript works great when it is located on the same domain as the SWF. But in one case, the HTML resides on domain A, the javascript and the flash both reside on domain B. I have done all of the following:

  • The embed tag has allowScriptAccess="always" (and the object has that as a param)
  • My SWF file's actionscipt has Security.allowDomain("*")
  • My SWF also calls Security.allowInsecureDomain("*")
  • Both domain A and domain B have a /crossdomain.xml file which has allow-access-from domain="*"

The SWF is able to call javascript on the page, but when I use Javascript to call functions exposed by ExternalInterface, I get

Error calling method on NPObject! [plugin exception: Error in Actionscript. Use a try/catch block to find error.]

This is ActionScript 2 so ExternalInterface.marshallExceptions is not available.

A: 

Since you are loading multiple swfs, you may need to include the security settings in each of those swfs on domain B that are loaded.

You may also need a loader context with the appropriate security settings.

import flash.system.LoaderContext;
import flash.system.ApplicationDomain;
import flash.system.Security;
import flash.system.SecurityDomain;
import flash.net.URLRequest;
import flash.net.URLLoader;

var context:LoaderContext = new LoaderContext(true, ApplicationDomain.currentDomain, (Security.sandboxType == Security.REMOTE) ? SecurityDomain.currentDomain : null);
var l:Loader = new Loader();
l.load(new URLRequest("http://example.com/myswf.swf"), context);
Alex Jillard
+2  A: 

You should only need two things for this to work:

1) allowscriptaccess=always will allow your swf to send stuff out to the page

2) System.security.allowDomain("yourhtmldomain.com");

Note that it's System.security.allowDomain() in AS2 - it's not the same as AS3 or what you have written above.

number 2 above allows the html page on domainA to call things in the swf on domainB.

The domain your js is hosted on won't matter here, since the browser embeds it on domainA, the script is executed in domainA.

crossdomain.xml is mainly only for loading remote files, which you aren't doing, so you can remove that if you like. (and you probably don't want to have a crossdomain.xml file with allow="*" sitting on your main domain, that's very bad practice)

Geoff
A: 

I'm having a similar problem and can't seem to resolve it with the solutions above. We have a loader architecture so our small AS3 loader (a Sprite) pulls in a Flex 3 Application which then pulls in various Flex 3 Modules. When I expose a callback via ExternalInterface.addCallback("foo", foo) in one of the loaded in Modules, I get the "Error calling method on NPObject!" error.

However, when I run ExternalInterface.addCallback("foo", loadedModule.foo) from the Loader Sprite or the Flex Application I don't have this issue. I've added allowDomain() calls to the Loader, Application and Module as well as passing ApplicationDomain.currentDomain and SecurityDomain.currentDomain when the App is loaded and when the Module is loaded.

Any ideas on why running addCallback() from the loaded Module doesn't expose the callback to JS?

@Rob: Welcome to StackOverflow! You should post a new question and reference my question in your question. That will allow you to receive answers from others.
Josh
A: 

Using AS3 with Flash Player version 10 I could not get ExternalInterface.addCallback() to work correctly for testing locally. I finally got my local copy working by adding the parameter "allowNetworking" with a value of "all" (http://www.adobe.com/livedocs/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00001079.html). Good luck to anyone struggling with this!

Robert Jones II