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

Posted

技术标签:

【中文标题】在 Chrome 中将 iframe 与本地文件一起使用【英文标题】:Using iframe with local files in Chrome 【发布时间】:2013-07-30 19:27:38 【问题描述】:

我很难弄清楚如何从外部页面访问加载到 iframe 中的页面。两个页面都是本地文件,我用的是 Chrome。

我有一个外页和许多内页。外部页面应该始终显示内部页面的页面标题(这在我的应用程序中是有意义的,在这个精简的示例中可能不那么有意义)。这在 AppJS 中没有任何问题,但我被要求让这个应用程序直接在浏览器中工作。我收到错误“Blocked a frame with origin "null" from access a frame with origin "null"。协议、域和端口必须匹配。”。

我认为这是由于 Chrome 对本地文件的同源政策,但这并没有帮助我直接解决问题。我可以通过使用每个Ways to circumvent the same-origin policy 的window.postMessage 方法来解决这个精简示例中的问题。但是,除了这个示例之外,我还想从外部页面操作内部页面的 DOM,因为这将使我的代码更加简洁 - 所以发布消息并不能完全完成这项工作。

外页

<!DOCTYPE html>
<html>
    <head> 
        <meta name="viewport">
    </head> 
    <body>
        This text is in the outer page
        <iframe src="html/Home.html" seamless id="PageContent_Iframe"></iframe>
        <script src="./js/LoadNewPage.js"></script>
    </body>
</html>

内页

<!DOCTYPE html>
<html>
    <head>
        <title id="Page_Title">Home</title> 
        <meta name="viewport">
    </head> 
    <body>
        This text is in the inner page
    </body>
</html>

javascript

var iFrameWindow = document.getElementById("PageContent_Iframe").contentWindow;
var pageTitleElement = iFrameWindow.$("#Page_Title");

根据Is it likely that future releases of Chrome support contentWindow/contentDocument when iFrame loads a local html file from local html file?,我尝试使用标志启动 Chrome

--allow-file-access-from-files

但结果没有变化。

根据Disable same origin policy in Chrome,我尝试使用标志启动 Chrome

--disable-web-security

但结果还是没有变化。

根据What does document.domain = document.domain do?,我让两个页面都运行命令

document.domain = document.domain;

这导致了错误“阻止了来源为“null”的框架访问来源为“null”的框架。请求访问的框架将“document.domain”设置为“”,但被访问的框架确实不是。两者都必须将“document.domain”设置为相同的值才能允许访问。"

为了好玩,我让两个页面都运行命令

document.domain = "foo.com";

这导致了错误“Uncaught Error: SecurityError: DOM Exception 18”。

我在挣扎。任何知识渊博的人的帮助都会很棒!谢谢!

【问题讨论】:

【参考方案1】:

很抱歉,我已经尝试了数周来解决这个问题(我的项目需要它),但我的结论是这是不可能的。

通过javascript和chrome进行本地访问有很多问题,其中一些可以使用--allow-file-access-from-files--disable-web-security解决,包括一些HTML5离线功能,但我绝对认为没有办法访问本地文件.

我建议您不要浪费时间试图绕过这一点,并尝试发布您可以解释到内页的消息,这样您就可以在那里进行 DOM 修改。

【讨论】:

男孩,这太糟糕了。非常感谢您的回复!【参考方案2】:

根据我们在一分钟前在我的立方体中的讨论:)

我在尝试使 AJAX 发布请求正常工作时遇到了同样的问题 (Ajax post response from express js keeps throwing error)。

让我感到困惑的不是直接从文件系统运行文件,而是从本地服务器运行它。我使用 node 来运行 express.js。您可以使用以下命令安装 express:npm install -g express

完成后,您可以使用以下命令创建一个 express 项目:express -s -e expressTestApp

现在,在该文件夹中,您应该会看到一个名为 app.js 的文件和一个名为 public 的文件夹。将您希望使用的 html 文件放在公用文件夹中。我将文件 app.js 替换为以下代码:

var express = require('/usr/lib/node_modules/express');
var app = express();

app.use(function(err, req, res, next)
  console.error(err.stack);
  res.send(500, 'Something broke!');
);

app.use(express.bodyParser());
app.use(express.static('public'));

app.listen(5555, function()  console.log("Server is up and running");  );

注意,require 行可能不同。您必须找到您的系统实际放置快递的位置。您可以使用以下命令执行此操作:sudo find / -name express

现在,使用以下命令启动 express Web 服务器:node app.js

此时,网络服务器已启动并正在运行。继续打开浏览器并导航到您的 IP 地址(或者如果您与服务器在同一台机器上,则为 127.0.0.1)。使用 ip 地址:portnumber\filename.html 其中端口号是我们创建的 app.js 文件中的 5555。

现在在那个浏览器中,您不应该(并且在我们测试它时没有)再遇到任何这些相同的问题。

【讨论】:

请注意,如果您安装了 Python,则可以应用您在此处建议的相同方法和set up a Web server one line:python -m SimpleHTTPServer [port] 哇,真是太好了。没有看到那个。我在相同的源代码上对其进行了测试,它可以工作,但比 express 慢。以如此之快的速度启动和运行是非常了不起的,当然也需要考虑权衡。 对于 Python 3,请改用:python -m http.server [port] 另一种选择是 Node 包 serve。全局安装后,您只需使用终端导航到该 html 目录并运行命令 serve(默认为端口 3000)或 serve -p [port]【参考方案3】:

file:// 协议和 http:// 协议在 iframe 方面表现得非常不同。我遇到了您在 PhoneGap 上使用文件协议访问本地 assets/www 文件夹中的所有本地文件的应用程序所描述的相同问题。

如果出于安全原因,现代浏览器似乎阻止使用 iframe 中的文件协议显示“本地”文件。

我们最终放弃了 iframe,只使用 div 作为“视口”。幸运的是,我们的应用程序的整体大小并没有那么大,所以我们设法将所有内容加载到一个页面中。

【讨论】:

我有点好奇这些安全原因是什么。老实说,我看不出有任何理由禁止这样做。如果有特定情况,如果 Chrome 可以提供合理的消息,那就太好了,因为我确实希望协议、域和端口对于一堆本地文件是相同的。 @JacekPrucia 我会破解:原因是如果有人给你一个访问本地文件的应用程序,那么如果 Chrome 没有阻止它,它可以继续读/写你的本地文件。 (如果您正在开发自己的应用程序并且只想访问自己的文件系统,这并不明显,但如果您将应用程序分发给其他人,则变得更加明显。) @martinjakubik 当然可以,但我仍然认为这没有什么害处。假设您的页面植根于“C:\Projects\Test\Test.html”。恶意页面只能在该特定文件夹中写入本地文件(应用于文件夹时的同源策略)。当然它可以创建恶意文件 - 伪装成无辜屏幕保护程序的应用程序,但是您仍然需要用户操作才能造成损害。如果您只是使用该应用程序,我仍然看不到它会以何种方式损坏本地系统。 @JacekPrucia 我不知道...我认为它仍然可以退出文件夹并覆盖(或读取)其他文件。 @martinjakubik 好吧......从技术上讲,它可以做到这一点。但是,由于它们确实将 http 协议访问限制为“同源策略”,因此它们也可以以几乎相同的方式限制文件协议。出于某种原因,他们没有费心想出一个场景,只是禁用了整个东西,迫使我使用本地网络服务器......

以上是关于在 Chrome 中将 iframe 与本地文件一起使用的主要内容,如果未能解决你的问题,请参考以下文章

使用 JQuery 访问由 chrome 扩展注入的 iframe

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

如何在我的扩展程序的新标签页中将其他扩展程序的新标签页加载为 iFrame

无法通过 chrome 扩展与 iFrame 交互

从 Chrome 内容脚本扩展访问 iframe

iframe.readyState 在 chrome 中不起作用