简体   繁体   English

使用文件协议调用Chrome中iframe中定义的JavaScript函数

[英]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. 这个问题非常类似于这里提出的问题的完全更新版本: 如何在Chrome / Webkit中使用文件协议将JavaScript函数从一个帧调用到另一个帧 - 遗憾的是,这个问题从未真正回答过。

I have an HTML page that contains an SVG image in an iframe. 我有一个HTML页面,其中包含iframe中的SVG图像。 The SVG exports a JavaScript API that allows it to do useful things (reset to zoomed and centered, display at "actual size"). SVG导出一个JavaScript API,允许它执行有用的操作(重置为缩放和居中,以“实际大小”显示)。 Below the iframe, I've put buttons that the user can click on that call through to the functions defined in the SVG. 在iframe下面,我将用户可以点击该按钮的按钮放到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!). 它在Safari,Firefox,甚至IE 9(支持SVG - 万岁!)中运行良好。 But on Chrome, it fails: the debugger informs me that: 但是在Chrome上,它失败了:调试器通知我:

Property 'reset' of object [object DOMWindow] is not a function . 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). 事实上,似乎确实如此:即使'contentWindow'是DOMWindow类型,它也没有方法或字段(至少,不是调试器会告诉我的)。 Even asking for its 'document' field fails (yields null). 甚至要求其“文档”字段失败(产生null)。

The rub appears to be the use of the file:// protocol to transfer both the containing HTML and the contained SVG. 摩擦似乎是使用file://协议来传输包含HTML和包含的SVG。 As noted in the question I referenced above, Chrome produces the following error when the attempt to access 'contentWindow' is made: 如上面引用的问题中所述,当尝试访问“contentWindow”时,Chrome会产生以下错误:

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." 我不想告诉别人“只是不使用Chrome - 它有愚蠢的安全概念。”

Is there no way to work around this restriction? 有没有办法解决这个限制?

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. 正如您所见,Web应用程序绝对没有办法允许这样做。

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. 因此,请使用以下命令打开Chrome:chrome.exe --allow-file-access-from-files ,用于开发。

Thanks to the information offered by @Mohamed Mansour, I was able to find more details on this issue. 感谢@Mohamed Mansour提供的信息,我能够找到有关此问题的更多详细信息。

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 ]. Chrome行为的基本原理是防止恶意制作的网页通过JavaScript和内部框架在您不知情的情况下访问您的文件系统内容并将数据上传到互联网[ Chromium bug 4197Chromium bug 47416 ]。

It is unfortunate, from my point of view, that the Chromium team chose to take things as far as they did. 从我的观点来看,Chromium团队选择尽可能地采取行动是不幸的。 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 ]. Gecko在攻击这个痣方面有点微妙:它将跨页脚本限制为同一子目录[ Mozilla bug 230606文件协议的同源策略 ]。 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. 对于用户和开发人员而言,结果并没有那么令人惊讶,并且产生了比Chrome的行为更多的焦虑 - 阅读Chromium bug 47416 ,特别是看看我的意思。

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." 这真的太糟糕了 - 我想支持Chrome,但是只要他们想要运行我的“网站”,就不能指望我的用户用一个模糊的命令行选项重新启动它。

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 . 我在这里发布我的调查结果以防其他人在我的问题中偶然发现Chrome似乎神秘地不适合他们,并鼓励任何读这篇文章的人考虑主演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. 开发人员已经明确表示,他们不愿意考虑改变Chrome的行为,除非人们真正关心这个问题。 Being told "I've had to tell users not to use Chrome" hasn't been enough encouragement. 被告知“我必须告诉用户不要使用Chrome”并没有得到足够的鼓励。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM