36

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

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

我认为这是由于 Chrome 对本地文件的同源策略,但这并没有帮助我直接解决问题。我可以通过使用 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");

Per当 iFrame 从本地 html 文件加载本地 html 文件时,Chrome 的未来版本是否可能支持 contentWindow/contentDocument?,我尝试使用标志启动 Chrome

--allow-file-access-from-files

但结果没有任何变化。

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

--disable-web-security

但是,结果再次没有变化。

根据document.domain = document.domain 做什么?,我让两个页面都运行命令

document.domain = document.domain;

这导致了错误“阻止了来源为“null”的框架访问来源为“null”的框架。请求访问的框架将“document.domain”设置为“”,但正在访问的框架没有。两者都必须设置“ document.domain" 设置为相同的值以允许访问。 "

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

document.domain = "foo.com";

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

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

4

3 回答 3

19

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

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

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

于 2013-07-30T15:08:59.850 回答
12

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

我遇到了同样的问题(来自 express js 的 Ajax 发布响应不断抛出错误)试图让 AJAX 发布请求正常工作。

解决这个问题的原因不是直接从文件系统运行文件,而是从本地服务器运行它。我使用 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。

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

于 2013-08-01T14:08:47.397 回答
3

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

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

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

于 2013-12-04T15:42:52.203 回答