10

I create an IFRAME dynamically in the following way:

var wrapUpIframe = document.createElement("iframe");
wrapUpIframe.id = 'WrapUpDialog3';
wrapUpIframe.src = 'WrapUpDialog.html';    
document.body.appendChild(wrapUpIframe);

after the dynamic creation my document.domain is being shortened from Servername.dc.com to only dc.com,

but when I try to access contentWindow I got an Access is denied error:

document.getElementById("WrapUpDialog3").contentWindow.SomeFunction();

Note: When I define the IFRAME statically in the HTML it works fine.
I also tried to change my IFRAME document.domain in the following way:

WrapUpDialog3.document.domain = dc.com;

I checked both document.domain and my IFRAME domain and they are both identical.

What can I do?

I'm working with IE9.

Martijn de Milliano
  • 3,908
  • 3
  • 36
  • 45
Dor Cohen
  • 16,769
  • 23
  • 93
  • 161
  • In what browser do you get this behavior? If I type your code into the Chrome debugger I can access `el.contentWindow` fine. Note that not just the domain needs to match but the full origin, so you might try to compare `document.location.origin` of the two windows. – Nik Haldimann Feb 21 '13 at 15:17
  • @nhaldimann I work with IE9 – Dor Cohen Feb 21 '13 at 15:19
  • This has been answered here: http://stackoverflow.com/questions/364952/jquery-javascript-accessing-contents-of-an-iframe Bertrand – Bertrand Mar 05 '13 at 19:49
  • 2
    @BertrandLefort But he said the origin is the same. – acme Mar 06 '13 at 08:30
  • What is `WrapUpDialog3`? And how do you access `contentWindow`? If you could post a more complete example then we might be able to help you better. – Martijn de Milliano Mar 06 '13 at 20:08
  • @MartijndeMilliano WrapUpDialog3 is just my iFrame id and I added an example to the use in my question – Dor Cohen Mar 07 '13 at 07:15
  • @DorCohen Have you tried to access the `iframe` via `frames` collection, like `window.frames[0].SomeFunction();`. – Teemu Mar 07 '13 at 19:38
  • What was the thing that solved the issue? There's a bunch of tips in the accepted answer... – crappish Jul 05 '13 at 15:57

3 Answers3

9

First take a look at the correct answer from this post. It looks to me like that could be your issue.

If not that then maybe this quick hack I saw from another post might help.

 var frame = $('<iframe>')
.attr('id', 'myIframe')
.addClass('someClass')
.attr('src', 'javascript:(function () {' +'document.open();document.domain=\'myDomain.net\';document.close();' + '})();');
.appendTo($('#someDiv'));

Not sure if this is relevant but I also found this on the web link.

OK, so to respond to your comment. The javascript function isn't assigning the source, it's setting the document domain which apparently doesn't get done correctly in I.E.

Check out this link for another example and explanation.

So what I would try might be something like this ...

var wrapUpIframe = document.createElement("iframe");
wrapUpIframe.id = 'WrapUpDialog3';    
wrapUpIframe.src = setSrc();
document.body.appendChild(wrapUpIframe);

function setSrc(){document.open();document.domain=\'dc.com\';document.close();return 'WrapUpDialog.html';}

You might have to play around with how to return the actual url for the iframe after running the function that sets the document domain. But from what I am seeing this might work for you.

I had a similar issue but not exactly the same problem which is why I can't give you an exact fix. The function setting the document domain was what got me past the access denied error.

You could also add this to your main document to really make sure the domains match.

 <script type="text/javascript">
    document.domain = 'dc.com';
  </script>

I also wanted to add a link for some explanation on explicitly setting the document.domain that I had used before. This was helpful to me in the past. Particularly this quote ...

Explicitly setting the value indicates intent to "cooperate" with a script on another subdomain (under the same parent domain).

Dor, you may be having a timing issue. I found some code (here) that I just tested that works for me. It makes sure that the iframe is loaded before you try to access the contentWindow.

var iframe = document.createElement("iframe");
iframe.src = "WrapUpDialog.html";

if (iframe.attachEvent){
    iframe.attachEvent("onload", function(){
        alert("Local iframe is now loaded.");
    });
} else {
    iframe.onload = function(){
        alert("Local iframe is now loaded.");
    };
}

document.body.appendChild(iframe);

var iframeWindow = iframe.contentWindow || iframe.contentDocument.parentWindow;
Community
  • 1
  • 1
Vic
  • 367
  • 2
  • 10
  • Thanks for the reply, my src should be an external html page - WrapUpDialog.html, how can load it using your suggestion? – Dor Cohen Mar 07 '13 at 07:14
  • Dor, are you trying to load the js functions you mentioned in this question (http://stackoverflow.com/questions/14849606/load-external-html-file-to-div-and-use-its-js-functions) in this html page? – Vic Mar 08 '13 at 14:47
  • 1
    Shame I didn't get the bounty. :) – Vic Apr 25 '13 at 15:25
  • Dor, if it was the timing issue that was the problem let me know. I'll edit my answer so that others know as well. – Vic May 29 '13 at 17:27
2

How do you serve your files? Do you see file:/// in your address bar? If so, try serving your code using a webserver.

Google Chrome gives an access denied error if I try your code using file:///, but it works when served from a local webserver (i.e. the address starts with http://localhost/).

Martijn de Milliano
  • 3,908
  • 3
  • 36
  • 45
1

Since you have not yet accepted any of the answers given you probably still have the problem.

Try setting document.domain explicitly in both HTML pages (you seem to be doing this in one page only). This means that as @Vic suggested, you need to add the following javascript code to the HTML that includes the iframe:

document.domain = 'dc.com';

This means that your code would look like this:

document.domain = 'dc.com';
var wrapUpIframe = document.createElement("iframe");
wrapUpIframe.id = 'WrapUpDialog3';
wrapUpIframe.src = 'WrapUpDialog.html';    
document.body.appendChild(wrapUpIframe);

Then, in WrapUpDialog.html itself (not in the main page because then you would circumvent the security system!) you need to set document.domain as well:

document.domain = dc.com;

So this line of yours will NOT work:

WrapUpDialog3.document.domain = 'dc.com';

because WrapUpDialog.html itself needs to grant permission to its "parent" page to execute its javascript.

There is more info on this page: What does document.domain = document.domain do?.

Final hint: do try your code using different browsers: IE9, Firefox, Google Chrome. This can help you identify whether you are perhaps dealing with a quirk of one particular browser.

Community
  • 1
  • 1
Martijn de Milliano
  • 3,908
  • 3
  • 36
  • 45