gleydson404 / flex-iframe

Automatically exported from code.google.com/p/flex-iframe
0 stars 0 forks source link

Problems with callIFrameFunction #3

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. call callIFrameFunction to call a function in the IFrame
2. there is no step two

Here is what I tried to debug the issue:

I pulled out the "generated" javascript for calling the
function-in-the-iframe--also called "callIFrameFunction"--and put it into a
static javascript file referenced by the index.template, so that I could
put a Firebug breakpoint inside that function. The function is called but
it bombs out at:

if (iframeDoc.wrappedJSObject != undefined)

I looked up "wrappedJSObject" and honestly do not completely understand it,
but I do understand a need to be able to dynamically get access to the
function in the iframe's page. It seems like "wrappedJSObject" might not
always be available? So I'm wondering if there is another way.

In the meantime I have an always-known set of 10 functions inside the
iframe that I need to call, so I can hard-code a function that will call
them by name. But in the future this is an awesome feature and an elegant
abstraction, I'd love to be able to use it.

What version of the product are you using? On what operating system?
IFrame 1.3.2
FB3
FF or IE7 on XP

Original issue reported on code.google.com by dealingwith on 4 Nov 2008 at 11:09

GoogleCodeExporter commented 9 years ago
Hi dealingwith,

I'm the one who added the callIFrameFunction to the component. I have a couple 
of questions for you:

- Are your main html page (that your Flex app is embedded within) and the URL 
of your iframe content in the same 
domain? The protocol, hostname, and port must match exactly, otherwise most 
browsers will refuse to allow 
JavaScript to talk between the host page and the iframe page. Example: if your 
flex app is at 
http://flex.mydomain.com and the content you're loading into your iframe is at 
http://html.mydomain.com, callIFrameFunction won't work because the browser 
perceives it as a cross-domain scripting violation. This is a 
feature of browser security and I don't think there's any way around it.

- What version of Firefox are you seeing this issue on? The wrappedJSObject 
stuff was developed for Firefox 2, and 
it's possible that it won't work right on Firefox 3 (which I unfortunately have 
not had time to do extensive testing 
on). However, this line should evaluate to false on IE and be ignored. If it's 
blowing up there too, I'm going to 
guess you are hitting a cross-domain security issue that is completely 
preventing attempted access to any 
properties on iframeDoc.

- Can you check in Firebug and see what type of object iframeDoc is right 
before it blows up? (Is it undefined, 
HTMLDocument, XPCNativeWrapper, or something else)

BTW, wrappedJSObject is there because Firefox (at least version 2 on Mac OS X) 
treats JavaScript inside the iframe 
as "unsafe", as though the calling JavaScript is chrome code executing in a XUL 
component (it's not, but it may be 
getting this treatment because of the way FlashPlayer is involved). As a 
result, it returns JS objects from inside the 
iframe within an "XPCNativeWrapper" object. wrappedJSObject unwraps these and 
allows access to the "unsafe" 
JavaScript inside. Mozilla has documentation on this here: 
https://developer.mozilla.org/en/XPCNativeWrapper

Original comment by ryan2...@gmail.com on 5 Nov 2008 at 6:54

GoogleCodeExporter commented 9 years ago
I have what might be a solution. I'm still in the middle of implementing it and 
am
still having problems with getting the arguments passed into the final 
javascript
function, but here is the "in-between" javascript function (called via iframe 
via
externalinterface):

function callIFrameFunction(iframeID, functionName, args)
{
var iframeEl = document.getElementById(iframeID);
var iframeWin;

if (iframeEl.contentWindow) { // IE and Safari require, but works for Firefox 
too
  iframeWin = iframeEl.contentWindow;
} else if (iframeEl.contentDocument) { // Works for Firefox, DOM level 2 
standard
  iframeWin = iframeEl.contentDocument.
}
return iframeWin[functionName](args);
}

Original comment by dealingwith on 7 Nov 2008 at 7:48

GoogleCodeExporter commented 9 years ago
Interesting. Glad you are getting into the JavaScript nitty gritty and trying 
things out.

It's my understanding that contentWindow returns a window object 
(http://www.w3schools.com/HTMLDOM/dom_obj_window.asp), which typically won't 
have the functions you want to call. 
Functions declared in a script tag are generally defined on the document object 
(http://www.w3schools.com/HTMLDOM/dom_obj_document.asp), which can be accessed 
from a property on the window object. 
Hence the contentWindow.document reference in my version of the function. But 
for all I know this may be changing as browsers 
evolve.

I just did some testing of this function (the currently published version) on 
both Firefox 2 and 3. It works, but only if both the flex 
app and the iframe content are coming from a remote server with the same 
domain. If I try to run the flex app locally in Firefox 
(i.e. using Debug or Run from FlexBuilder), it doesn't work. It has to be 
uploaded to the same website as the iframe content .html 
and accessed there. Safari on the other hand seems to be less strict and allows 
this crossover from local to remote domain 
without a problem.

Original comment by ryan2...@gmail.com on 7 Nov 2008 at 10:20

GoogleCodeExporter commented 9 years ago
Actually this does not appear to be the case.   At least not for me.   I have 
tried 
to use this both locally where I develop as well as on a remote server using 
IE6, 7, 
8 and FF3 and in all casses the function is never called.  Still working with 
it and 
using the latest iframe code.   Any help would, but an example code to be sure 
it is 
not user error on my part would be best.

Original comment by bob.tate...@gmail.com on 29 Jul 2009 at 6:06

GoogleCodeExporter commented 9 years ago
I have an iFrame page that I need to call javascript funtions on via a Flex
interface.  Has anyone gotten callIframeFunction to work?

Original comment by lancels...@gmail.com on 11 Aug 2009 at 12:37

GoogleCodeExporter commented 9 years ago
@lancelsims

Can you provide some more information about the environment you're trying to 
use this in?

At minimum, we'd need to know:

- Browser type and version(s) you've tried

- Source domain of your IFrame content and your Flex app (note that these 
absolutely must be the same for this to 
work - i.e. trying to access functions inside an IFrame from app1.domain.com, 
when the Flex app is running on 
app2.domain.com, will not work). 

- How your JavaScript functions are defined in the IFrame page (script tag? 
separate .js file? included where? head? 
body?)

I have been able to successfully use callIFrameFunction in Safari 3 and Firefox 
up to 3.0.x. I have not yet tested it 
in Firefox 3.5, nor in Safari 4. It's possible that browser security models 
have changed in ways that break this. (In 
general, one page calling JS on another, which is what's happening when calling 
into an IFrame, is very dicey. It's 
becoming more and more locked down due to cross-site scripting vulnerabilities)

Original comment by ryan2...@gmail.com on 11 Aug 2009 at 6:14

GoogleCodeExporter commented 9 years ago
I was having a similar issue and what was happening was that in Firefox 
atleast, the
function was undefined when being called by
document.getElementByID(iframeID).contentDocument[functionName](args); so I 
hardcoded
it to the following case and it works for firefox 3.5 at least, untested for 
IE, but
I believe it works there too.

private static var FUNCTION_CALLIFRAMEFUNCTION:String =
"document.insertScript = function ()" +
                "{ " +
                    "if (document.callIFrameFunction==null)" +
                    "{" +
                        "callIFrameFunction = function (iframeID, functionName, args)" +
                    "{" +
                        "var iframeRef=document.getElementById(iframeID);" +
                        "var iframeDoc = iframeRef.contentWindow;" +
                        " return iframeDoc[functionName](args);" +
                    "}" +
                "}" +
            "}";

Original comment by itala...@gmail.com on 8 Oct 2009 at 4:49

GoogleCodeExporter commented 9 years ago
This issue is pretty old, I think some of what has been said here may now be 
deprecated. I'm merging it into Issue 69, please open new issues if needed.

Original comment by Julien.N...@gmail.com on 14 May 2010 at 4:33