local xmlhttprequest from sandboxed page in chrome

2019-08-03 15:52发布

问题:

I have a packaged app that embeds a app-local page in an iframe (to embed libraries doing forbidden stuff). My sandboxed page wants to make an xmlhttprequest to a relative URL (so still in the same extension), but it is refused with the following message:

XMLHttpRequest cannot load chrome-extension://nilibhiopchihkgnnecfblfjegmogpgn/libs/fonts/miss_fajardose/MissFajardose-Regular.ttf. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

To tell the truth, I found the relevant documentations:

  • http://developer.chrome.com/apps/manifest/sandbox.html
  • http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#attr-iframe-sandbox

    But they make no sense to me, maybe it's the mix of colors and ADD.

A bit of context: I am using the same code inside my chrome web app and on the internet, in this instance I am loading a font, typesetting something and computing a toolpath for contouring the text. If the page is the chrome app there is a button to send it to the router, if it is on the web you can just see the toolpath.

回答1:

After about a half day of my life poking around, here's the best workaround I found. From sandboxed page, postmessage to parent asking for local file to be loaded:

window.top.postMessage({ XMLFile: "levels/foo.xml" }, "*");

In nonsandboxed page, initiate async load of file, then call back down to the sandboxed page with the string version of the file:

document.body.onload = function() {
    // Listen for request messages from child window
    window.addEventListener("message", function (event) {
        if (event.data.XMLFile) {
            // Load the requested XML file, must be async
            var xhttp = new XMLHttpRequest();

            xhttp.open("GET", event.data.XMLFile, true);
            xhttp.send(null);

            // After loading, pass the resulting XML back down to sandboxed page
            xhttp.onload = function (e) {
                document.getElementById("idSandbox").contentWindow.postMessage({ sResponseText: xhttp.responseText }, '*');
            }
        }
    } );
}

Returning to the sandboxed page, when you receive the xml response text, convert it back into a DOM object for parsing:

// Receive messages from containing window
window.addEventListener("message", function (event) {
    // XML file retrieved
    if (event.data.sResponseText) {
        parser = new DOMParser();
        xmlDoc = parser.parseFromString(event.data.sResponseText, "text/xml");

        onAfterLoadLevel(xmlDoc);
    }
});

As an aside, the mix of colors on that whatwg page would trigger ADD in anybody that didn't already have it. The other reference pages were useless. There were a number of discussions about this issue but nobody has posted the code so I figured I'd do it here.