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

Posted

技术标签:

【中文标题】使用文件协议在 Chrome 中调用 iframe 中定义的 JavaScript 函数【英文标题】:Call a JavaScript function defined in an iframe in Chrome using the file protocol 【发布时间】:2011-07-03 22:27:48 【问题描述】:

此问题与此处提出的问题的完全更新版本极为相似:How to call a javascript function from one frame to another in Chrome/Webkit with file protocol — 不幸的是,该问题从未真正得到回答。

我有一个在 iframe 中包含 SVG 图像的 html 页面。 SVG 导出一个 JavaScript API,允许它做有用的事情(重置为缩放和居中,以“实际大小”显示)。在 iframe 下方,我将用户可以单击该调用的按钮放置到 SVG 中定义的函数中。

我的代码如下所示:

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

它在 Safari、Firefox 甚至 IE 9(支持 SVG——万岁!)中都能完美运行。但在 Chrome 上,它失败了:调试器告诉我:

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

事实上,这似乎是事实:即使 'contentWindow' 是 DOMWindow 类型,它也没有方法或字段(至少,调试器不会向我显示)。甚至请求它的“文档”字段也会失败(返回 null)。

问题似乎是使用 file:// 协议来传输包含的 HTML 和包含的 SVG。正如我在上面提到的问题中所指出的,当尝试访问“contentWindow”时,Chrome 会产生以下错误:

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

总的来说,我认为安全性很好;这看起来像是一个受安全启发的限制。但是在这里,它似乎走得太远了:毕竟,这些是用户文件系统上的文件,就我而言,甚至在同一个目录中。

托管代码不是一种选择——它必须驻留在用户的机器上。我不想告诉人们“不要使用 Chrome——它有愚蠢的安全概念。”

有没有办法绕过这个限制?

【问题讨论】:

【参考方案1】:

当然没有办法 :) 这些文件协议是由用户显式调用的。正如您所见,Web 应用程序绝对不可能允许这样做。

这样做的唯一方法是如果您“作为用户”允许这种情况发生,如果是这样,您可以通过添加以下命令行参数来启用它:

// 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

所以打开 Chrome 使用:chrome.exe --allow-file-access-from-files 这是用于开发的。

【讨论】:

是的 - 这就是诀窍。谢谢你。但是为什么会如此封闭? File-to-HTTP 或 HTTP-to-File 或...对我来说很有意义。但是文件到文件?一定有一些我没有考虑到的安全漏洞。【参考方案2】:

感谢@Mohamed Mansour 提供的信息,我能够找到有关此问题的更多详细信息。

Chrome 行为的基本原理是防止恶意制作的页面通过 JavaScript 和内部框架在您不知情的情况下访问文件系统的内容并将数据上传到 Internet [Chromium bug 4197, Chromium bug 47416]。

在我看来,不幸的是,Chromium 团队选择了他们所做的事情。 Gecko 在打击这个痣方面更加微妙:它将跨页脚本限制在相同的子目录中 [Mozilla bug 230606, Same-origin policy for file protocol]。结果对于用户和开发人员来说并不那么令人惊讶,并且比 Chrome 的行为所产生的焦虑要少得多——请阅读 Chromium bug 47416 以了解我的意思。

由于这种行为,我不得不修改我的“网站”——它不能托管在 Internet 上,必须驻留在本地用户的机器上——以便它弹出一个对话框,告诉用户切换浏览器。真是太糟糕了——我想支持 Chrome,但我不能指望我的用户在他们想运行我的“网站”时用一个不起眼的命令行选项重新启动它。

我在这里发布我的发现,以防其他人在 Chrome 似乎神秘地不适用于他们时偶然发现我的问题,并鼓励任何阅读此内容的人考虑主演 Chromium bug 47416。开发人员痛苦地明确表示,除非很明显人们真的关心这个问题,否则他们不愿意考虑改变 Chrome 的行为。被告知“我不得不告诉用户不要使用 Chrome”并没有得到足够的鼓励。

【讨论】:

很抱歉之前没有回复,您已经做了很好的研究 :) 不幸的是,File API 仍在制作中,希望 HTML5 能够解决大多数用户的需求。我理解拥有这样的命令行选项的挫败感,它可以改进。希望将来会这样:)

以上是关于使用文件协议在 Chrome 中调用 iframe 中定义的 JavaScript 函数的主要内容,如果未能解决你的问题,请参考以下文章

在 Chrome 中将 iframe 与本地文件一起使用

iframe.readyState 在 chrome 中不起作用

jQuery/iframe 在 Chrome 中不起作用

从 Chrome 内容脚本扩展访问 iframe

如何在 iframe 中设置 Chrome 打印对话框的默认文件名?

iframe如何在chrome扩展中访问父窗口