locked
Access Denied on post back in iFrame RRS feed

  • Question

  • I have an iFrame that is resized on the parent when the content height is changed.

    It is working fine, except on post back's. In that case the parent is getting an 'access denied' when it tries to access the iFrame content.

    Parent and iFrame is on the same domain.

    What can be wrong?


    • Edited by Bart.NET Monday, March 10, 2014 4:16 PM typo
    Monday, March 10, 2014 4:16 PM

Answers

  • I found the problem (quit dump, I have to commit...)

    One of my approaches was...and the most logic...to detect the content changes in the iFrame. But nothing happens on the resize event.

    And the winner was...I forgot to reference the jquery library jquery.ba-resize.js inside the iFrame page

    There was no javascript error because the default jquery also has an resize event, but this one only fires when the window size changes.

    So this is a working solution (from IE8 to 10, firefox and chrome)

    On the parent:

    <iframe id="myFrame" src="#" width="100%" style="height: 100%" frameborder="0" scrolling="no" allowtransparency></iframe>
    <script type="text/javascript">
        $(function () {
            var iframe = $('#myFrame'); 
    
            var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
            var eventer = window[eventMethod];
            var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
    
            // Listen to message from iFrame resize
            eventer(messageEvent, function (e) {
                iframe.css({ height: e.data });
            }, false);
    
            // Update src in iFrame
            iframe.attr('/somePage.aspx', src);
        });
    </script>

    And in the inner page (the somePage.aspx page that is the src in the iFrame):

       <script type="text/javascript">
            $(function () {
                //setup resize listener
                try {
                    var myForm = $('#myForm');
                    myForm.resize(function () {
                        var elem = $(this);
                        window.parent.postMessage(elem.outerHeight(true), '*');
                    });
                    myForm.resize();
                } catch (e) {
                    alert(e.message);
                }
            });
        </script>

    and referenced the jquery.ba-resize.js in the somePage.aspx page

    Thanks to you all

    Monday, March 17, 2014 9:06 AM

All replies

  • The postMessage did it from the iFrame to the parent.

    Only I can't figer out how to assign an event listener in the iFrame when it content size changes.

    var myIFrame= $('#MyIFrame');
    //=>the resize event below is never fired
    myIFrame.resize(function (e) {
                        var elem = $(this);
                        window.parent.postMessage(elem.outerHeight(true), '*');
                    });

    thanks

    btw, I did it from outside the iFrame, the event is triggered, but I got the access denied again on a postback.

    Tuesday, March 11, 2014 5:06 PM
  • Hi,

    can you post a url to a mashup or your site that shows the issue. "On postback"... I presume that is an asp.net postback called from the iframe content page?

    use an asp.net update panel instead of an embedded iframe. or... a jquery dialog.

    IE and FX do not support the seamless attribute...Webkit partially supports it.

    thx.


    Rob^_^

    here is a mashup that works.

    iframeresize.htm

    <!DOCTYPE html>
    <html>
    
    <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <title>iframeResize</title>
    </head>
    
    <body>
    <iframe src="resizeme.htm"></iframe>
    </body>
    
    </html>
    

    resizeme.htm

    <!DOCTYPE html>
    <html>
    
    <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <script type="text/javascript">
    function resizeme(){
    	if(window.frameElement){
    	window.frameElement.style.width='400px';
    	
    	
    	}
    }
    </script>
    <title>resizeme</title>
    </head>
    
    <body>
    <div id="divContent">
    <button type="button" onclick="resizeme()">Resize</button>
    </div>
    </body>
    
    </html>
    

    Wednesday, March 12, 2014 12:16 AM
  • It is indeed an asp.net app that is moving from old aspx to MVC.

    So the parent is already MVC. But the iFrame is still rendering old aspx pages with ascx controls in it.

    In the current time frame we don't have the option to convert the old aspx to MVC views.

    So the sizing issue is working fine as long there is no post back.

    When the content in the iFrame is changing, the iFrame tag on the parent is sizing correct.

    Only when I do a submit, and the size of the aspx page is changing, I got an 'access denied'. What I forgot to mention, I don't have it in all browsers. in IE9 it is not working, in Firefox latest version it is working fine.

    This is an extract of the parent page:

    <!DOCTYPE html> <html> <head> <title>Main Page</title> <script src="Scripts/jquery-1.9.1.js" type="text/javascript"></script> <script src="Scripts/jquery.ba-resize.js" type="text/javascript"></script> </head> <body> <iframe id="myFrame" src="#" width="100%" style="height: 100%" scrolling="no"></iframe> <script type="text/javascript"> $(function() { var iframe = $('#myFrame'); var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent"; var eventer = window[eventMethod]; var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message"; // Listen to message from iFrame resize eventer(messageEvent, function(e) { iframe.css({ height: e.data }); }, false); var src = location.protocol + '//' + location.host + '/OldPage.aspx'; iframe.load(function() { try {

    =>on the following line, the access denied occurs when inner page is post back

    =>When I move this code to the old page, the resize is not triggered on content changes

    =>two options: I find a solution for the access denied

    var iframeContent = iframe.contents().find('body'); var innerform = iframeContent.find('#innerform'); innerform.resize(function () { var elem = $(this); window.parent.postMessage(elem.outerHeight(true), '*'); }); innerform.resize(); } catch (e) { //if access denied, refresh parent parent.location.href = parent.location.href; } }); // Update src in iFrame iframe.attr('src', src); }); </script> </body> </html>

    and this the old aspx page:

    <!DOCTYPE html>
    <head runat="server">
        <title>Sample</title>
        <script src="Scripts/jquery-1.9.1.js" type="text/javascript"></script>
        <script src="Scripts/jquery.ba-resize.js" type="text/javascript"></script>
    </head>
    <body>
        <form id="innerform" runat="server">
            Sample Page rendered in iFrame
            <button onclick="$('#innerform').submit()"></button> <%--After post back, and is the content resizes, an access denied on the parent page happens--%>
        </form>
    </body>


    • Edited by Bart.NET Thursday, March 13, 2014 9:01 AM typo
    Thursday, March 13, 2014 9:00 AM
  • It is indeed an asp.net app that is moving from old aspx to MVC.

    So the parent is already MVC. But the iFrame is still rendering old aspx pages with ascx controls in it.

    In the current time frame we don't have the option to convert the old aspx to MVC views.

    So the sizing issue is working fine as long there is no post back.

    When the content in the iFrame is changing, the iFrame tag on the parent is sizing correct.

    Only when I do a submit, and the size of the aspx page is changing, I got an 'access denied'. What I forgot to mention, I don't have it in all browsers. in IE9 it is not working, in Firefox latest version it is working fine.

    This is an extract of the parent page:

    <!DOCTYPE html> <html> <head> <title>Main Page</title> <script src="Scripts/jquery-1.9.1.js" type="text/javascript"></script> <script src="Scripts/jquery.ba-resize.js" type="text/javascript"></script> </head> <body> <iframe id="myFrame" src="#" width="100%" style="height: 100%" scrolling="no"></iframe> <script type="text/javascript"> $(function() { var iframe = $('#myFrame'); var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent"; var eventer = window[eventMethod]; var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message"; // Listen to message from iFrame resize eventer(messageEvent, function(e) { iframe.css({ height: e.data }); }, false); var src = location.protocol + '//' + location.host + '/OldPage.aspx'; iframe.load(function() { try {

    =>on the following line, the access denied occurs when inner page is post back

    =>When I move this code to the old page, the resize is not triggered on content changes

    =>two options: I find a solution for the access denied

    var iframeContent = iframe.contents().find('body'); var innerform = iframeContent.find('#innerform'); innerform.resize(function () { var elem = $(this); window.parent.postMessage(elem.outerHeight(true), '*'); }); innerform.resize(); } catch (e) { //if access denied, refresh parent parent.location.href = parent.location.href; } }); // Update src in iFrame iframe.attr('src', src); }); </script> </body> </html>

    and this the old aspx page:

    <!DOCTYPE html>
    <head runat="server">
        <title>Sample</title>
        <script src="Scripts/jquery-1.9.1.js" type="text/javascript"></script>
        <script src="Scripts/jquery.ba-resize.js" type="text/javascript"></script>
    </head>
    <body>
        <form id="innerform" runat="server">
            Sample Page rendered in iFrame
            <button onclick="$('#innerform').submit()"></button> <%--After post back, and is the content resizes, an access denied on the parent page happens--%>
        </form>
    </body>


     Can you post a publicly accessible link instead please...

    see http://benalman.com/projects/jquery-postmessage-plugin/

    http://benalman.com/code/projects/jquery-resize/examples/resize/


    Rob^_^

    It appears (from your use of postback.aspx) that you are trying to implement the FBConnect api in an iframe....

    this cannot be done... you need window.open(fbconnecturl) and your parent page (where you call the fbconnect url) and your postback page need to be in the same https folder on your server....

    You cannot test your 'login using facebook' links on your local server as FB servers will not find your postback.aspx page.

    Saturday, March 15, 2014 4:09 AM




  • So Bart.  It turns out that injecting a handler into the iframe.onresize from the parent side of the element causes a problem.  Maybe it's part of the problem you're seeing.


    To explain.  Above, you see I cooked up yet another demo.  Online here.  If you look closely at my previous demo, you'll notice it reported the wrong "source" of the postMessage.  This new demo gets it right.  It was pretty tricky to make that to happen.


    What was happening is this.  There is an object called the Window Proxy.  It is what we're actually accessing whenever we access properties within any window (or iframe contentWindow).  The way I read the W3C specs, each such "browsing context" window gets its own Window Proxy.  I guess this came about when tabbed browsing began, since there is a main window which hosts all the tab windows.  If you look at how W3C defines the postMessage event.source value, you'll see it speaks of the Browsing Context of the sender.  I don't think that's ambiguous, but maybe it is?


    Here's how that connects to this current discussion.  When we write the iframe's onresize property from the parent window side of that element, we're actually talking to it through our parent window proxy, who (somehow) communicates to the iframe's side.  Then, when the onresize event fires, it (somehow) sets the postMessage source to be the parent's browsing context proxy.  That's what I illustrated above in the lower screenshot.  It wasn't my bug.  That's really where the Message event.source said the message came from.


    I had to do some hackery to get around that, and get the onresize handler to actually execute within the iframe's actual browsing context.


    I think this subtle discrepancy of which browsing context your onresize handler operates in could be the cause of the permissions issues.  Here are the W3C specs on this:


    dev.w3.org/html5/postmsg/#dom-messageevent-source

    www.w3.org/TR/2009/WD-html5-20090423/browsers.html#browsing-context

    www.w3.org/TR/2009/WD-html5-20090423/browsers.html#windowproxy




    Separately.  While experimenting with this Proxy thing, I also tried the postMessage method from a popup window for comparison.  Yikes.  Talk about weird problems.  Here's an msdn blog which says postMessage hasn't worked right (between windows/tabs) since IE8, and still doesn't with IE11.


    blogs.msdn.com/b/ieinternals/archive/2009/09/16/bugs-in-ie8-support-for-html5-postmessage-sessionstorage-and-localstorage.aspx



    @sillybee@domitriNickoff - your eating wind again. Totally off track.

    Rob^_^

    Monday, March 17, 2014 12:20 AM
  • I found the problem (quit dump, I have to commit...)

    One of my approaches was...and the most logic...to detect the content changes in the iFrame. But nothing happens on the resize event.

    And the winner was...I forgot to reference the jquery library jquery.ba-resize.js inside the iFrame page

    There was no javascript error because the default jquery also has an resize event, but this one only fires when the window size changes.

    So this is a working solution (from IE8 to 10, firefox and chrome)

    On the parent:

    <iframe id="myFrame" src="#" width="100%" style="height: 100%" frameborder="0" scrolling="no" allowtransparency></iframe>
    <script type="text/javascript">
        $(function () {
            var iframe = $('#myFrame'); 
    
            var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
            var eventer = window[eventMethod];
            var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
    
            // Listen to message from iFrame resize
            eventer(messageEvent, function (e) {
                iframe.css({ height: e.data });
            }, false);
    
            // Update src in iFrame
            iframe.attr('/somePage.aspx', src);
        });
    </script>

    And in the inner page (the somePage.aspx page that is the src in the iFrame):

       <script type="text/javascript">
            $(function () {
                //setup resize listener
                try {
                    var myForm = $('#myForm');
                    myForm.resize(function () {
                        var elem = $(this);
                        window.parent.postMessage(elem.outerHeight(true), '*');
                    });
                    myForm.resize();
                } catch (e) {
                    alert(e.message);
                }
            });
        </script>

    and referenced the jquery.ba-resize.js in the somePage.aspx page

    Thanks to you all

    Monday, March 17, 2014 9:06 AM