Search code examples
javascripthtmliframegoogle-chromefile-uri

Call a JavaScript function defined in an iframe in Chrome using the file protocol


This question is extremely similar to the fully-updated version of the question asked here: How to call a JavaScript function from one frame to another in Chrome/Webkit with file protocol — unfortunately, that question was never actually answered.

I have an HTML page that contains an SVG image in an iframe. The SVG exports a JavaScript API that allows it to do useful things (reset to zoomed and centered, display at "actual size"). Below the iframe, I've put buttons that the user can click on that call through to the functions defined in the SVG.

My code looks like this:

function reset() {
  document.getElementByID('iframe').contentWindow.reset();
}

It works perfectly in Safari, Firefox, and even IE 9 (which supports SVGs - hooray!). But on Chrome, it fails: the debugger informs me that:

Property 'reset' of object [object DOMWindow] is not a function.

And indeed, there does seem to be truth to that: even though 'contentWindow' is of type DOMWindow, it has no methods or fields (at least, not that the debugger will show me). Even asking for its 'document' field fails (yields null).

The rub appears to be the use of the file:// protocol to transfer both the containing HTML and the contained SVG. As noted in the question I referenced above, Chrome produces the following error when the attempt to access 'contentWindow' is made:

Attempt to access frame with URL file://[...]/contained.svg from frame with URL file://[...]/container.html. Domains, protocols and ports must match.

In general, I think security is great; this looks like a security-inspired restriction. But here, it seems to have gone too far: these are files on the user's filesystem, after all, and in my case, are even in the same directory.

Hosting the code is not an option - it must reside on the user's machine. I'd hate to have to tell people "just don't use Chrome - it has silly notions of security."

Is there no way to work around this restriction?


Solution

  • Of course there is no way :) These file protocols are meant to be explicitly called by the user. There is absolutely no way for a web application to allow that, as you have seen.

    The only way to do that is if you "as a user" allowed that to happen, if so, you can enable that by adding the following command line parameter:

    // By default, file:// URIs cannot read other file:// URIs. This is an
    // override for developers who need the old behavior for testing.
    --allow-file-access-from-files
    

    So open up Chrome with: chrome.exe --allow-file-access-from-files this is used for development.