Search code examples
javascriptgoogle-chromeiframelocalcross-site

How to test browser for permission before "Unsafe JavaScript attempt to access frame with URL" (Chrome local frame)?


The HTML parent window and iFrame content know about each other and communicate freely when they live on the same web server. When they are saved to DVD, Chrome throws an "Unsafe JavaScript attempt to access frame with URL" when iFrame tries to contact top as a local file.

The catch below catches the permission error, but the error is still registered by the browser and visible to the user.

Is it possible to test first if this access is allowed before attempting to access to preclude the unsafe JavaScript error?

           // Called from script in an iframe
           function findSiblingIFrame(sibId) {
                 try {
                       var sibFrame = top.document.getElementById(sibId);
                       if (sibFrame != null) {
                           alert("found sibling iframe");
                       } else {
                           alert("did not find sibling iframe");
                       }
                   }
                   catch (err) {
                      alert("not allowed to find sibling iframe");
                      // Would rather test if permission first to prevent
                      // browser from registering the error.
                   }
           }

Solution

  • I ended up using HTML5 messaging to pass potential sandboxed requests up and down the iframe hierarchy.

    For example, each html page in a nested iframe hierarchy has access to the following javascript. If the caught HTML5 message request cannot be executed locally, the message is passed up to the parent. The parent can also pass messages down to iframes. This only works because all the pages have access to the same javascript file.

    // function to handle message request
    function messageHandler(argJSON) {
        // A collection of available functions for inbound messages
        var msgFunctionMap = new Object();
        msgFunctionMap.removeBorder = removeBorder;
        msgFunctionMap.restoreBorder = restoreBorder;
        // ...more
        // try execute request
        try {
            var jsonObj = JSON.parse(argJSON.data);
            msgFunctionMap[jsonObj.request](jsonObj.args);
        }
        catch (err) {
            alert(" Request not supported: " + argJSON.data);
        }
    };
    // example function to remove object id x's border if it exists in "this" window, else pass request up
    var removeBorder = function (jsonMsg, argObj) {
        var xiFrame = document.getElementById("x");
        if (xiFrame != null) {
            xiOrigWidth = xiFrame.style.borderWidth;
            xiFrame.style.borderWidth = '0px';
        }
        // Otherwise, pass message up else if (window.parent && window.parent.postMessage) {
            window.parent.postMessage(jsonMsg.data, "*");
        }
    };
    //... more
    // pass predefined message request from child to parent
    function messageUpHandler(message) {
        if (window.parent && window.parent.postMessage) {
            window.parent.postMessage(message.data, "*");
        }
    };
    // Listener for child messages
    if (window.addEventListener) {
        window.addEventListener("message", messageUpHandler, true);
    }