Printable Version of Topic

Click here to view this topic in its original format

HTMLHelp Forums _ Client-side Scripting _ Cross origin security error although the iframe is on the same domain

Posted by: RainLover May 30 2014, 05:12 AM

I get a security error in console when I click the button:

CODE
var iframe = document.getElementById('iframe'),
            button = document.getElementById('button');
                button.onclick = function () {
            iframe.src = 'linked-frame.html';
            iframe.contentDocument.body.style.background = 'red';
        };


http://dl.dropboxusercontent.com/u/4017788/Labs/cross-origin-security-error.html

Posted by: Christian J May 30 2014, 07:05 AM

Maybe it's because the parent page is hosted at dl.dropboxusercontent.com, the default framed page is hosted at www.example.com, and when clicking the button the framed page host changes to dl.dropboxusercontent.com?

Test if it the error disappears if all three pages are hosted at the same domain.

Posted by: RainLover May 30 2014, 07:49 AM

QUOTE(Christian J @ May 30 2014, 07:05 AM) *

Maybe it's because the parent page is hosted at dl.dropboxusercontent.com, the default framed page is hosted at www.example.com, and when clicking the button the framed page host changes to dl.dropboxusercontent.com?

Test if it the error disappears if all three pages are hosted at the same domain.

But it shouldn't throw such an error as I change the iframe source in my function.

Posted by: Christian J May 30 2014, 08:08 AM

QUOTE(RainLover @ May 30 2014, 02:49 PM) *

But it shouldn't throw such an error as I change the iframe source in my function.

Agreed. Perhaps is has something to do with the default domain being external, I suspect browsers are not very sophisticated in this regard (I recall some Chromium based browser caused similar errors even with local files, because it didn't recognize the file system as belonging to the same "domain").

Also, are you sure it's the color change that trigs the error (sometimes error logs don't match the exact code line)? In particular, do you still get an error if you use only

CODE
button.onclick = function () {
            iframe.src = 'linked-frame.html';
        }

? And how about using a same-domain default frame URL?

Posted by: RainLover May 30 2014, 08:15 AM

QUOTE(Christian J @ May 30 2014, 08:08 AM) *

Also, are you sure it's the color change that trigs the error (sometimes error logs don't match the exact code line)? In particular, do you still get an error if you use only

CODE
button.onclick = function () {
            iframe.src = 'linked-frame.html';
        }


No errors.


QUOTE

And how about using a same-domain default frame URL?

I can't use the same-domain as default URL.

Posted by: Christian J May 30 2014, 09:25 AM

Have you tried clicking the button a second time? For me that causes the framed page to go red for a moment, then go back to default/white again. wacko.gif

Maybe the browser tries to change color before the new framed page has actually loaded. In that case, maybe you could use an onload event on the framed page and change color only after that.

Even better might be to change color from a script in the framed page itself. Perhaps you could send data from the parent page to the framed page with a querystring in the URL.



Posted by: pandy May 30 2014, 11:34 AM

I don't know why, but the problem seems to have to do with changing the page in the iframe. It doesn't even work if you just relaod the same page. I can't spot what's wrong with doing it the way you do.

CODE
    <iframe src="linked-frame.html" id="iframe"></iframe>
    <input type="button" value="Color it!" id="button">
    <script>
        var iframe = document.getElementById('iframe'),
            button = document.getElementById('button');
            button.onclick = function () {
            iframe.src = 'linked-frame.html';
            iframe.contentDocument.body.style.background = 'red';
        };
    </script>

Posted by: Christian J May 30 2014, 01:00 PM

QUOTE(Christian J @ May 30 2014, 03:08 PM) *

(I recall some Chromium based browser caused similar errors even with local files, because it didn't recognize the file system as belonging to the same "domain").

Here's what it says when I try a local file:

"Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "null" from accessing a frame with origin "null". Protocols, domains, and ports must match."


Posted by: Christian J May 30 2014, 01:20 PM

This works in all my browsers when loaded from a server:

CODE

<iframe src="http://example.org" id="iframe"></iframe>
<input type="button" value="Color it!" id="button">
<script>
var iframe = document.getElementById('iframe'),
button = document.getElementById('button');
button.onclick = function ()
{
    iframe.src = 'linked-frame.html';
    iframe.onload=function()
    {
        this.contentDocument.body.style.background = 'red';
    }
};
</script>

(it also works from the file system except in Chromium, see my post above).

Posted by: RainLover May 30 2014, 01:23 PM

QUOTE(Christian J @ May 30 2014, 01:20 PM) *

This works in all my browsers when loaded from a server:
CODE

<iframe src="http://example.org" id="iframe"></iframe>
<input type="button" value="Color it!" id="button">
<script>
var iframe = document.getElementById('iframe'),
button = document.getElementById('button');
button.onclick = function ()
{
    iframe.src = 'linked-frame.html';
    iframe.onload=function()
    {
        this.contentDocument.body.style.background = 'red';
    }
};
</script>

(it also works from the file system except in Chromium, see my post above).


Thanks for the answer! But it gives the same error message if click on the link inside the red iframe: http://dl.dropboxusercontent.com/u/4017788/Labs/cross-origin-security-error2.html.

Posted by: Christian J May 30 2014, 02:11 PM

QUOTE(RainLover @ May 30 2014, 08:23 PM) *

it gives the same error message if click on the link inside the red iframe

Seems the onload event is called again when you click the link, as shown by the alertbox below:

CODE
var iframe = document.getElementById('iframe'),
button = document.getElementById('button');
button.onclick = function ()
{
    iframe.src = 'linked-frame.html';
    iframe.onload=function()
    {
        alert('load');
        this.contentDocument.body.style.background = 'red';

    }
};

--I would have thought that such a nested onload event would only fire after the onclick, but I don't know enough about javascript to tell. unsure.gif

Anyway here's an crude workaround, I'm sure someone else can come up with something neater:

CODE
var iframe = document.getElementById('iframe'),
button = document.getElementById('button');
var clicked='no';
button.onclick = function ()
{
    clicked='yes';
    iframe.src = 'linked-frame.html';
    iframe.onload=function()
    {
        if(clicked=='yes')
        {
            this.contentDocument.body.style.background = 'red';
            clicked='no';
        }
    }
};

Posted by: pandy May 30 2014, 03:46 PM

The demo page works for me now (several browsers) but it doesn't contain an empty iframe to start with. but http://example.com. What did you do to make it work? unsure.gif

Posted by: Christian J May 30 2014, 05:08 PM

There are two demo pages, I recall both have used http://example.com as default all the time.

Posted by: Frederiek May 30 2014, 05:18 PM

The first demo flashed red and back again and throwing a js error. The second demo (in post 10) works for me too without any error.

Though I didn't know about contentDocument, leaving it out (just using iframe.body.style.background = 'red';) works now too.

Safari 6/Mac

Posted by: pandy May 30 2014, 05:20 PM

QUOTE(Christian J @ May 31 2014, 12:08 AM) *

There are two demo pages, I recall both have used http://example.com as default all the time.



I don't know if it has changed, I hadn't looked at the second page before. I meant it wasn't as in your example.

But thing is, why does it work when the original example didn't?

Posted by: Christian J May 30 2014, 05:49 PM

QUOTE(Frederiek @ May 31 2014, 12:18 AM) *

The second demo (in post 10) works for me too without any error.

The button works fine on that page.

Instead there's a new error when you click the link to http://example.com on the linked-frame.html page --don't you get that in Safari Mac? The link click apparently fires the onload event again when the http://example.com page is loaded, which in turn makes the script try to that style page, which isn't allowed and produces the new error (I think). happy.gif



Posted by: Christian J May 30 2014, 05:57 PM

QUOTE(pandy @ May 31 2014, 12:20 AM) *

I hadn't looked at the second page before. I meant it wasn't as in your example.

It's almost the same, and seems to work the same.

QUOTE
But thing is, why does it work when the original example didn't?

My theory is that the onload event in demo2 delays the styling until the local framed page is loaded. Without the onload the browser apparently tries to style the third party default page.


Posted by: RainLover May 30 2014, 08:51 PM

QUOTE(Christian J @ May 30 2014, 02:11 PM) *

Anyway here's an crude workaround, I'm sure someone else can come up with something neater:

CODE
var iframe = document.getElementById('iframe'),
button = document.getElementById('button');
var clicked='no';
button.onclick = function ()
{
    clicked='yes';
    iframe.src = 'linked-frame.html';
    iframe.onload=function()
    {
        if(clicked=='yes')
        {
            this.contentDocument.body.style.background = 'red';
            clicked='no';
        }
    }
};


Thank you very much! I think here's the neater way: http://dl.dropboxusercontent.com/u/4017788/Labs/cross-origin-security-error3.html.

Posted by: Frederiek May 31 2014, 02:42 AM

QUOTE(Christian J @ May 31 2014, 12:49 AM) *

QUOTE(Frederiek @ May 31 2014, 12:18 AM) *

The second demo (in post 10) works for me too without any error.

The button works fine on that page.

Instead there's a new error when you click the link to http://example.com on the linked-frame.html page --don't you get that in Safari Mac? The link click apparently fires the onload event again when the http://example.com page is loaded, which in turn makes the script try to that style page, which isn't allowed and produces the new error (I think). happy.gif

I hadn't clicked that link, but indeed that throws 2 errors, one for the domain mismatch and a typeError : 'null' is not an object (evaluating 'iframe.contentDocument.body').

The third demo works fine, no errors, correct coloring.

Posted by: pandy May 31 2014, 04:54 AM

QUOTE(Christian J @ May 31 2014, 12:57 AM) *

It's almost the same, and seems to work the same.


Yeah, sorry. I thought yours has an empty iframe to start with. I must read the tread again. Must have missed something essential.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)