在 Chrome 中对本地文件使用 iframe

IT技术 javascript google-chrome iframe same-origin-policy appjs
2021-01-19 02:08:42

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

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

我认为这是由于 Chrome 关于本地文件的同源策略,但这并没有帮助我直接解决问题。我可以通过使用 window.postMessage 方法 per Ways to bypass the same-origin policy 来解决这个精简示例中的问题然而,除了这个例子之外,我还想从外页操作内页的 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

但结果没有任何变化。

根据在 Chrome 中禁用同源策略,我尝试使用标志启动 Chrome

--disable-web-security

但结果再次没有变化。

document.domain = document.domain 有什么作用?,我让两个页面都运行命令

document.domain = document.domain;

这导致错误“阻止了一个原点为“空”的框架访问原点为“空”的框架。请求访问的框架将“document.domain”设置为“”,但被访问的框架没有。两者都必须设置“ document.domain" 为相同的值以允许访问。 "

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

document.domain = "foo.com";

这导致了错误“未捕获的错误:SecurityError:DOM Exception 18 ”。

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

3个回答

我很抱歉地告诉你,我已经在几周内尝试解决这个问题(我需要它用于一个项目),我的结论是这是不可能的。

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

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

孩子,这太糟糕了。非常感谢您的回复!
2021-03-18 02:08:42

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

我遇到了同样的问题(来自 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

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

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

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

请注意,如果您安装了 Python,您可以应用您在此处建议的相同方法并在一行设置 Web 服务器python -m SimpleHTTPServer [port]
2021-03-21 02:08:42
另一种选择是 Node 包serve全局安装后,您只需使用终端导航到该 html 目录并简单地运行命令serve(默认为端口 3000)或serve -p [port].
2021-03-22 02:08:42
哇,真是太好了。没有看到那个。我在相同的源代码上测试了它,它可以工作,但比 express 慢。以如此快的速度启动并运行是非常了不起的,当然需要考虑权衡。
2021-03-30 02:08:42
对于 Python 3,请改用它: python -m http.server [port]
2021-04-05 02:08:42

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

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

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

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