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

5.7k views Asked by At

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?

2

There are 2 answers

1
Mohamed Mansour On BEST ANSWER

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.

1
M. Anthony Aiello On

Thanks to the information offered by @Mohamed Mansour, I was able to find more details on this issue.

The rationale for Chrome's behavior is to prevent a maliciously-crafted page from, through JavaScript and internal frames, accessing the contents of your file system without your knowledge and upload data to the Internet [Chromium bug 4197, Chromium bug 47416].

It is unfortunate, from my point of view, that the Chromium team chose to take things as far as they did. Gecko is a bit more subtle in whacking this mole: it limits cross-page scripts to same-subdirectories [Mozilla bug 230606, Same-origin policy for file protocol]. The result is much less surprising for users and developers and has generated much, much less angst than has arisen over Chrome's behavior — read Chromium bug 47416 in particular to see what I mean.

Because of this behavior, I've had to modify my "website" — which cannot be hosted on the Internet and must reside on local-users' machines — so that it throws up a dialog box telling users to switch browsers. It's really too bad — I'd like to support Chrome but just can't expect my users to relaunch it with an obscure command-line option whenever they want to run my "website."

I'm posting my findings here in case anyone else stumbles across my question when Chrome seems to mysteriously not work for them and also to encourage anyone who reads this to consider starring Chromium bug 47416. The developers have made it painfully clear that they are unwilling to consider changing Chrome's behavior unless it's clear people really care about the issue. Being told "I've had to tell users not to use Chrome" hasn't been enough encouragement.