2013-07-30 35 views
35

Mam trudny czas dowiedzieć się, jak uzyskać dostęp do strony załadowanej w elemencie iframe ze strony zewnętrznej. Obie strony to pliki lokalne i używam Chrome.Używanie elementu iframe z lokalnymi plikami w przeglądarce Chrome

Mam zewnętrzną stronę i wiele wewnętrznych stron. Strona zewnętrzna powinna zawsze wyświetlać tytuł strony dla strony wewnętrznej (ma to sens w mojej aplikacji, być może mniej w tym przykładowym przykładzie). Działa to bezproblemowo w AppJS, ale poproszono mnie, aby ta aplikacja działała bezpośrednio w przeglądarce. Występuje błąd "Zablokowano ramkę z początkiem" null "dostępu do ramki z początkiem" null ".Pliki, domeny i porty muszą się zgadzać".

Sądzę, że jest to spowodowane zasadami Chrome dotyczącymi pochodzenia dla plików lokalnych, ale to nie pomogło mi bezpośrednio rozwiązać problemu. Mogę obejść problem w tym uproszczonym przykładzie za pomocą metody window.postMessage na Ways to circumvent the same-origin policy. Jednak wychodząc poza ten przykład, chcę również manipulować DOMem strony wewnętrznej z zewnętrznej strony, ponieważ dzięki temu mój kod stanie się znacznie czyściejszy, więc wysyłanie wiadomości nie będzie w pełni wykonywać zadania.

zewnętrzna strona

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

Strona wewnętrzna

<!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 Is it likely that future releases of Chrome support contentWindow/contentDocument when iFrame loads a local html file from local html file? starałem uruchomienie Chrome z flagą

--allow-file-access-from-files 

Ale nie było zmian w wynikach.

Per Disable same origin policy in Chrome, próbowałem uruchomieniu Chrome z flagą

--disable-web-security 

Ale znowu nie było zmiany w wynikach.

Per What does document.domain = document.domain do?, miałem obie strony uruchomić polecenie

document.domain = document.domain; 

Spowodowało to błąd "zablokowanych ramkę z pochodzenia«null»dostępu ramkę z pochodzenia«null». The dostępu ramki żądania ustaw "document.domain" na "", ale ramka, do której uzyskiwany był dostęp, nie ma.Zarówno musi ustawić "document.domain" na tę samą wartość, aby umożliwić dostęp. "

Dla zabawy, miałem obie strony uruchomić polecenie

document.domain = "foo.com"; 

Powoduje to błąd "Uncaught Error: SecurityError: DOM Exception 18".

Jaję się. Każda pomoc od bardziej doświadczonych ludzi byłaby fantastyczna! Dzięki!

Odpowiedz

12

Per naszej dyskusji w moim kostki przed chwilą :)

uderzę ten sam problem (Ajax post response from express js keeps throwing error), próbując dostać się do żądania POST AJAX działa poprawnie.

To, co mnie dookoła, nie uruchamia pliku bezpośrednio z systemu plików, ale zamiast tego uruchamia go z lokalnego serwera. Użyłem węzła do uruchomienia pliku express.js. Można zainstalować ekspresowych za pomocą następującego polecenia: npm install -g express

Gdy to osiągnąć, można stworzyć wyraźną projektu za pomocą następującego polecenia: wyrazić -s -e expressTestApp

Teraz w tym folderze, należy zobacz plik o nazwie app.js i folder o nazwie public. Umieść pliki html, którymi chcesz pracować, w folderze publicznym. Zastąpiłem plik app.js następującym kodem:

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"); }); 

Uwaga, wiersz wymagający może być inny. Musisz znaleźć miejsce, w którym twój system rzeczywiście wyraża ekspresję. Można to zrobić za pomocą następującego polecenia: sudo find/-name wyrazić

Teraz zaczynają wyraźnej serwera WWW za pomocą następującego polecenia: węzeł app.js

w tym czasie, serwer WWW jest działa i działa. Śmiało, otwórz przeglądarkę i przejdź do swojego adresu IP (lub jeśli jesteś na tym samym komputerze, co serwer, 127.0.0.1). Użyj adresu ip: numer_portu \ filename.html, gdzie numer portu to 5555 w pliku app.js, który utworzyliśmy.

Teraz w tej przeglądarce nie powinno się (i nie było, gdy testowaliśmy) mieć już te same problemy.

+7

Zauważ, że jeśli masz zainstalowany Python, możesz zastosować to samo podejście, które sugerujesz tutaj, i [skonfigurować jeden serwer sieciowy] (http://stackoverflow.com/a/532710/710446): 'python -m SimpleHTTPServer [ port] ' – apsillers

+0

Wow, to naprawdę miłe. Nie widziałem tego. Przetestowałem go na tym samym kodzie źródłowym i działa, ale wolniej niż ekspresowo. Uruchomienie tego tak szybko jest niesamowite i na pewno trzeba wziąć pod uwagę kompromis. – Brian

+1

W Pythonie 3 użyj tego: 'python -m http.server [port]' – taleinat

17

Przykro mi to mówić, że próbowałem rozwiązać ten problem przez kilka tygodni (potrzebowałem go do projektu), a moim wnioskiem jest to, że nie jest to możliwe.

Istnieje wiele problemów związanych z lokalnym dostępem za pośrednictwem javascript z chrome, a niektóre z nich można rozwiązać za pomocą --allow-file-access-from-files i --disable-web-security, w tym niektóre funkcje offline HTML5, ale zdecydowanie myślę, że nie ma sposobu na dostęp do lokalnych plików.

Polecam, aby nie tracić czasu na próbowanie obejścia tego i próba opublikowania wiadomości, które można zinterpretować na stronach wewnętrznych, aby można było tam wykonać modyfikacje DOM.

+0

Chłopcze, szkoda. Bardzo dziękuję za odpowiedź! – ATTD

2

file: // protokół i protokół http: // powodują, że zachowanie się w przypadku elementów pływających jest bardzo różne. Miałem te same problemy, które opisujesz za pomocą aplikacji na PhoneGap, która używa protokołu plików, aby uzyskać dostęp do wszystkich lokalnych plików w folderze local assets/www.

Jeśli wydaje się, że nowoczesne przeglądarki uniemożliwiają wyświetlanie "lokalnych" plików przy użyciu protokołu plików w elementach iframe ze względów bezpieczeństwa.

Skończyło się na wysyłaniu elementów iframe i po prostu użyciu elementów div jako "rzutni". Na szczęście ogólny rozmiar naszej aplikacji nie był tak duży, więc udało nam się załadować wszystko na jednej stronie.

+0

Jestem trochę ciekawy, jakie są te powody bezpieczeństwa. Szczerze mówiąc nie widzę powodu, dla którego powinno to być zabronione. Jeśli istnieje konkretny przypadek, byłoby wspaniale, gdyby Chrome mógł dostarczyć sensowną wiadomość, ponieważ oczekuję, że protokół, domena i port będą takie same dla wielu lokalnych plików. –

+0

@JacekPrucia Zrobię crack: powód jest taki, że jeśli ktoś daje ci aplikację, która uzyskuje dostęp do plików lokalnych, to jeśli Chrome jej nie zablokuje, może zacząć czytać i zapisywać twoje lokalne pliki. (Nie jest to oczywiste, jeśli pracujesz nad własną aplikacją i chcesz tylko uzyskać dostęp do własnego systemu plików, ale staje się to bardziej oczywiste, jeśli rozpowszechniasz swoją aplikację na innych.) –

+0

@martinjakubik Oczywiście, może, ale nadal nie widzę szkodzi w tym. Załóżmy, że twoja strona jest zakorzeniona w "C: \ Projects \ Test \ Test.html". Złośliwa strona może zapisywać tylko pliki lokalne w tym folderze (ta sama polityka pochodzenia, gdy jest zastosowana do folderów). Pewnie, że może tworzyć złośliwe pliki - aplikacje, które maskują niewinne wygaszacze ekranu, jednak nadal potrzebujesz działania użytkownika, aby zadać obrażenia. Jeśli po prostu korzystasz z aplikacji, nadal nie widzę, w jaki sposób może ona uszkodzić lokalny system. –

Powiązane problemy