Использование iframe с локальными файлами в Chrome

Мне сложно понять, как получить доступ к странице, загруженной в 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");

Согласно Вероятно, что будущее выпуски Chrome поддерживают contentWindow / contentDocument, когда iFrame загружает локальный html-файл из локального html-файла?, я попытался запустить Chrome с флагом

--allow-file-access-from-files

Но в результатах не было изменений.

Согласно Отключить ту же политику происхождения в Chrome, я попытался запустить Chrome с флагом

--disable-web-security

Но опять же никаких изменений в результатах.

Согласно Что делает document.domain = document.domain?, я на обеих страницах была запущена команда

document.domain = document.domain;

Это привело к ошибке «Заблокировал фрейм с источником« null »от доступа к фрейму с источником« null ». Для кадра, запрашивающего доступ, для« document.domain »было установлено значение« », но для кадра, к которому осуществлялся доступ, этого не удалось. Оба должен установить для "document.domain" то же значение, чтобы разрешить доступ. "

Ради интереса я заставил обе страницы запустить команду

document.domain = "foo.com";

Это привело к ошибке «Неперехваченная ошибка: SecurityError: DOM Exception 18».

Я барахтаюсь. Любая помощь более знающих людей была бы фантастической! Спасибо!


person Aurora Tiffany-Davis    schedule 30.07.2013    source источник


Ответы (3)


Согласно нашему обсуждению в моем кубе минуту назад :)

Я столкнулся с той же проблемой (ответ на сообщение Ajax от express js продолжает бросать error), пытаясь заставить почтовый запрос AJAX работать правильно.

Что меня привлекло, так это то, что файл не запускается непосредственно из файловой системы, а запускается с локального сервера. Я использовал node для запуска express.js. Вы можете установить экспресс с помощью следующей команды: npm install -g 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");  });

Обратите внимание: требуемая строка может быть другой. Вы должны найти, где ваша система действительно помещает экспресс. Вы можете сделать это с помощью следующей команды: sudo find / -name express

Теперь запустите экспресс-веб-сервер с помощью следующей команды: node app.js

В настоящее время веб-сервер запущен и работает. Идите вперед, откройте браузер и перейдите к своему IP-адресу (или, если вы находитесь на том же компьютере, что и ваш сервер, 127.0.0.1). Используйте IP-адрес: номер_порта \ имя_файла.html, где номер порта - 5555 в созданном нами файле app.js.

Теперь в этом браузере у вас (и не было, когда мы его тестировали) больше не должно быть подобных проблем.

person Brian    schedule 01.08.2013
comment
Обратите внимание, что если у вас установлен Python, вы можете применить тот же подход, который вы предлагаете здесь, и настроить веб-сервер в одну строку: python -m SimpleHTTPServer [port] - person apsillers; 01.08.2013
comment
Вау, это действительно хорошо. Не видел этого. Я тестировал его на том же исходном коде, и он работает, но медленнее, чем экспресс. Быть готовым к работе так быстро - это удивительно, и, безусловно, стоит подумать о компромиссе. - person Brian; 01.08.2013
comment
В Python 3 используйте вместо этого: python -m http.server [port] - person taleinat; 15.07.2014
comment
Другой альтернативой является пакет Node serve. После того, как вы установили его глобально, вы можете просто перейти с помощью своего терминала в этот html-каталог и просто запустить команду serve (по умолчанию будет порт 3000) или serve -p [port]. - person travellingprog; 23.09.2015

С сожалением вынужден сообщить, что в течение нескольких недель я пытался решить эту проблему (мне это было нужно для проекта), и я пришел к выводу, что это невозможно.

Существует множество проблем, связанных с локальным доступом через javascript с хромом, и некоторые из них могут быть решены с помощью --allow-file-access-from-files и --disable-web-security, включая некоторые автономные функции HTML5, но я определенно думаю, что нет возможности получить доступ к локальным файлам.

Я рекомендую вам не терять время, пытаясь обойти это, и попытаться публиковать сообщения, которые вы можете интерпретировать, на внутренних страницах, чтобы вы могли там вносить изменения в DOM.

person panthalassa    schedule 30.07.2013
comment
Мальчик, это очень плохо. Тем не менее, большое спасибо за ваш ответ! - person Aurora Tiffany-Davis; 31.07.2013

Протоколы file: // и http: // заставляют вещи вести себя по-разному в отношении фреймов. У меня были те же проблемы, которые вы описываете, с приложением на PhoneGap, которое использует файловый протокол для доступа ко всем локальным файлам в папке local assets / www.

Кажется, что современные браузеры предотвращают отображение "локальных" файлов с помощью файлового протокола в iframe из соображений безопасности.

Мы закончили тем, что сбросили фреймы и просто использовали div как «области просмотра». К счастью, общий размер нашего приложения был не таким большим, поэтому нам удалось загрузить все на одной странице.

person Peter Drinnan    schedule 04.12.2013
comment
Мне любопытно, что это за соображения безопасности. Честно говоря, я не вижу причин, по которым это должно быть запрещено. Если есть конкретный случай, было бы здорово, если бы Chrome мог предоставить разумное сообщение, поскольку я ожидаю, что протокол, домен и порт будут одинаковыми для группы локальных файлов. - person Jacek Prucia; 10.05.2016
comment
@JacekPrucia Я попробую: причина в том, что если кто-то дает вам приложение, которое обращается к локальным файлам, то, если Chrome не блокирует его, он может продолжить чтение / запись ваших локальных файлов. (Это не очевидно, если вы работаете над своим собственным приложением и просто хотите получить доступ к своей собственной файловой системе, но это становится более очевидным, если вы распространяете свое приложение среди других.) - person martin jakubik; 29.07.2016
comment
@martinjakubik Конечно, может, но я все равно не вижу в этом вреда. Предположим, ваша страница находится в C: \ Projects \ Test \ Test.html. Вредоносная страница может записывать только локальные файлы в эту конкретную папку (та же политика происхождения при применении к папкам). Конечно, он может создавать вредоносные файлы - приложения, которые маскируются под невинную заставку, однако вам все равно нужно действие пользователя для нанесения ущерба. Если вы просто используете приложение, я все еще не понимаю, каким образом оно может повредить локальную систему. - person Jacek Prucia; 29.07.2016
comment
@JacekPrucia Я этого не знал ... Я думал, что он все еще может выйти из папки и перезаписать (или прочитать) другие файлы. - person martin jakubik; 31.07.2016
comment
@martinjakubik ну ... технически он может это сделать. Однако, поскольку они ограничивают доступ к протоколу http одной и той же политикой происхождения, они также могут ограничивать протокол файлов почти таким же образом. По какой-то причине они не удосужились придумать сценарий и просто отключили все это, заставив меня использовать локальный веб-сервер ... - person Jacek Prucia; 17.08.2016